14 #include <string_view> 19 #include <hilti/rt/autogen/config.h> 20 #include <hilti/rt/exception.h> 21 #include <hilti/rt/filesystem.h> 22 #include <hilti/rt/result.h> 23 #include <hilti/rt/types/set_fwd.h> 24 #include <hilti/rt/types/time.h> 25 #include <hilti/rt/types/vector_fwd.h> 29 void internalError(
const std::string& msg) __attribute__((noreturn));
33 #undef TINYFORMAT_ERROR 34 #define TINYFORMAT_ERROR(reason) throw ::hilti::rt::FormattingError(reason) 35 #include <hilti/rt/3rdparty/tinyformat/tinyformat.h> 36 #include <hilti/rt/extension-points.h> 37 #include <hilti/rt/fmt.h> 39 extern const char* __hlto_scope;
66 uint64_t cached_fibers;
73 extern std::optional<std::string>
getenv(
const std::string& name);
84 hilti::rt::filesystem::path
normalizePath(
const hilti::rt::filesystem::path& p);
91 inline std::string_view
rtrim(std::string_view s,
const std::string& chars) noexcept {
92 s.remove_suffix(s.size() -
93 [](
size_t pos) {
return pos != std::string_view::npos ? pos + 1 : 0; }(s.find_last_not_of(chars)));
102 inline std::string_view
ltrim(std::string_view s,
const std::string& chars) noexcept {
103 s.remove_prefix(std::min(s.find_first_not_of(chars), s.size()));
113 inline std::string_view
trim(std::string_view s,
const std::string& chars) noexcept {
118 constexpr
char whitespace_chars[] =
" \t\f\v\n\r";
126 inline std::string_view
rtrim(std::string_view s) noexcept {
return rtrim(s, detail::whitespace_chars); }
133 inline std::string_view
ltrim(std::string_view s) noexcept {
return ltrim(s, detail::whitespace_chars); }
140 inline std::string_view
trim(std::string_view s) noexcept {
return trim(s, detail::whitespace_chars); }
148 std::vector<std::string_view>
split(std::string_view s, std::string_view delim);
155 std::vector<std::string_view>
split(std::string_view s);
163 extern std::pair<std::string, std::string>
split1(std::string s);
171 extern std::pair<std::string, std::string>
rsplit1(std::string s);
179 extern std::pair<std::string, std::string>
split1(std::string s,
const std::string& delim);
187 extern std::pair<std::string, std::string>
rsplit1(std::string s,
const std::string& delim);
194 std::string
replace(std::string s, std::string_view o, std::string_view n);
201 inline bool startsWith(
const std::string& s,
const std::string& prefix) {
return s.find(prefix) == 0; }
207 template<
typename T,
typename TIter = decltype(std::begin(std::declval<T>())),
208 typename = decltype(std::end(std::declval<T>()))>
213 bool operator!=(
const iterator& other)
const {
return iter != other.iter; }
218 auto operator*()
const {
return std::tie(i, *iter); }
220 struct iterable_wrapper {
222 auto begin() {
return iterator{0, std::begin(iterable)}; }
223 auto end() {
return iterator{0, std::end(iterable)}; }
225 return iterable_wrapper{std::forward<T>(iterable)};
247 std::string expandEscapes(std::string s);
260 std::string escapeBytes(std::string_view s,
bool escape_quotes =
false,
bool use_octal =
false);
274 std::string escapeUTF8(std::string_view s,
bool escape_quotes =
false,
bool escape_control =
true,
275 bool keep_hex =
false);
282 std::string
join(
const T& l,
const std::string& delim =
"") {
286 for (
const auto& i : l ) {
289 result += std::string(i);
302 template<
typename T,
typename Allocator>
307 template<
typename C,
typename Y>
308 constexpr
auto transform_result_value(
const C&) {
309 using X =
typename C::value_type;
311 if constexpr ( std::is_same_v<C, std::vector<X>> ) {
312 return std::vector<Y>();
314 else if constexpr ( std::is_same_v<C, std::set<X>> ) {
315 return std::set<Y>();
321 else if constexpr ( std::is_same_v<C,
Set<X>> ) {
331 template<
typename C,
typename F>
333 using Y =
typename std::result_of_t<F(typename C::value_type&)>;
335 auto y = detail::transform_result_value<C, Y>(x);
336 std::transform(std::begin(x), std::end(x), std::inserter(y, std::end(y)), f);
365 template<
class Iter,
typename Result>
367 if ( base < 2 || base > 36 )
368 throw OutOfRange(
"base for numerical conversion must be between 2 and 36");
371 throw InvalidArgument(
"cannot decode from empty range");
373 std::optional<Result> n = std::nullopt;
381 else if ( *it ==
'+' ) {
386 for ( ; it != e; ++it ) {
390 if ( c >=
'0' && c <
'0' + base )
392 else if ( c >=
'a' && c <
'a' - 10 + base )
394 else if ( c >=
'A' && c <
'A' - 10 + base )
399 n = n.value_or(
Result()) * base + d;
418 template<
typename I1,
typename I2>
419 inline I1
pow(I1 base, I2 exp) {
436 template<
typename T,
typename F, std::size_t... Is>
437 constexpr
auto map_tuple(T&& tup, F& f, std::index_sequence<Is...> ) {
438 return std::make_tuple(f(std::get<Is>(std::forward<T>(tup)))...);
441 template<
typename T, std::size_t... Is>
442 auto join_tuple(T&& tup, std::index_sequence<Is...> ) {
443 std::vector<std::string> x = {
rt::to_string(std::get<Is>(std::forward<T>(tup)))...};
444 return join(x,
", ");
447 template<
typename T, std::size_t... Is>
449 std::vector<std::string> x = {rt::to_string_for_print(std::get<Is>(std::forward<T>(tup)))...};
450 return join(x,
", ");
455 template<
typename F, std::size_t I = 0,
typename... Ts>
457 if constexpr ( I ==
sizeof...(Ts) )
460 func(std::get<I>(tup));
461 tuple_for_each<F, I + 1>(tup, func);
469 template<
typename T,
typename F, std::
size_t TupSize = std::tuple_size_v<std::decay_t<T>>>
471 return detail::map_tuple(std::forward<T>(tup), f, std::make_index_sequence<TupSize>{});
480 template<
typename T, std::
size_t TupSize = std::tuple_size_v<std::decay_t<T>>>
482 return detail::join_tuple(std::forward<T>(tup), std::make_index_sequence<TupSize>{});
491 template<
typename T, std::
size_t TupSize = std::tuple_size_v<std::decay_t<T>>>
493 return detail::join_tuple_for_print(std::forward<T>(tup), std::make_index_sequence<TupSize>{});
500 template<
typename... T>
512 namespace detail::adl {
528 std::string
strftime(
const std::string& format,
const Time& time);
542 Time strptime(
const std::string& buf,
const std::string& format);
548 const auto tmpdir = hilti::rt::filesystem::temp_directory_path();
549 auto template_ = (tmpdir /
"hilti-rt-test-XXXXXX").native();
550 auto path = ::mkdtemp(template_.data());
552 throw RuntimeError(
"cannot create temporary directory");
561 if ( ! hilti::rt::filesystem::exists(_path) )
565 hilti::rt::filesystem::permissions(_path, hilti::rt::filesystem::perms::all);
566 for (
const auto& entry : hilti::rt::filesystem::recursive_directory_iterator(_path) )
567 hilti::rt::filesystem::permissions(entry, hilti::rt::filesystem::perms::all);
570 hilti::rt::filesystem::remove_all(_path, ec);
573 const auto& path()
const {
return _path; }
577 _path = std::move(other._path);
582 hilti::rt::filesystem::path _path;
586 template<
typename... Hashes>
587 constexpr std::size_t hashCombine(std::size_t hash1, std::size_t hash2, Hashes... hashes) {
588 auto result = hash1 ^ (hash2 << 1);
590 if constexpr (
sizeof...(hashes) > 0 )
591 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:332
bool isDebugVersion()
Definition: util.cc:34
std::string_view rtrim(std::string_view s, const std::string &chars) noexcept
Definition: util.h:91
std::string_view ltrim(std::string_view s, const std::string &chars) noexcept
Definition: util.h:102
void internalError(const std::string &msg) __attribute__((noreturn))
Definition: logging.cc:17
Definition: optional.h:79
std::string replace(std::string s, std::string_view o, std::string_view n)
Definition: util.cc:377
hilti::rt::filesystem::path normalizePath(const hilti::rt::filesystem::path &p)
Definition: util.cc:102
std::pair< std::string, std::string > split1(std::string s)
Definition: util.cc:156
bool startsWith(const std::string &s, const std::string &prefix)
Definition: util.h:201
hilti::rt::Result< hilti::rt::filesystem::path > createTemporaryFile(const std::string &prefix="")
Definition: util.cc:84
void cannot_be_reached() __attribute__((noreturn))
Definition: util.cc:52
std::string strftime(const std::string &format, const Time &time)
Definition: util.cc:412
void tuple_for_each(const std::tuple< Ts... > &tup, F func)
Definition: util.h:456
constexpr auto map_tuple(T &&tup, F f)
Definition: util.h:470
std::vector< std::string_view > split(std::string_view s, std::string_view delim)
Definition: util.cc:112
Time strptime(const std::string &buf, const std::string &format)
Definition: util.cc:438
auto join_tuple_for_print(T &&tup)
Definition: util.h:492
std::optional< std::string > getenv(const std::string &name)
Definition: util.cc:77
ByteOrder
Definition: util.h:504
constexpr auto enumerate(T &&iterable)
Definition: util.h:209
Iter atoi_n(Iter s, Iter e, uint8_t base, Result *result)
Definition: util.h:366
std::pair< std::string, std::string > rsplit1(std::string s)
Definition: util.cc:163
std::string join(const T &l, const std::string &delim="")
Definition: util.h:282
std::string version()
Definition: util.cc:22
ByteOrder systemByteOrder()
Definition: util.cc:390
auto join_tuple(T &&tup)
Definition: util.h:481
void abort_with_backtrace() __attribute__((noreturn))
Definition: util.cc:44
ResourceUsage resource_usage()
Definition: util.cc:54
std::string_view trim(std::string_view s, const std::string &chars) noexcept
Definition: util.h:113
I1 pow(I1 base, I2 exp)
Definition: util.h:419
std::string linker_scope()
Definition: util.h:53