12 #include <string_view>
17 #include <hilti/rt/3rdparty/ArticleEnumClass-v2/EnumClass.h>
18 #include <hilti/rt/exception.h>
19 #include <hilti/rt/filesystem.h>
20 #include <hilti/rt/result.h>
21 #include <hilti/rt/types/set_fwd.h>
22 #include <hilti/rt/types/time.h>
23 #include <hilti/rt/types/vector_fwd.h>
37 #define HILTI_RT_ENUM_WITH_DEFAULT(name, default_, ...) \
39 enum Value : int64_t { __VA_ARGS__ }; \
40 constexpr name(int64_t value = default_) noexcept : _value(value) {} \
41 friend name Enum(Value value) { return name(value); } \
42 friend constexpr bool operator==(const name& a, const name& b) noexcept { return a.value() == b.value(); } \
43 friend constexpr bool operator!=(const name& a, const name& b) noexcept { return ! (a == b); } \
44 friend constexpr bool operator<(const name& a, const name& b) noexcept { return a.value() < b.value(); } \
45 constexpr int64_t value() const { return _value; } \
61 #define HILTI_RT_ENUM(name, ...) HILTI_RT_ENUM_WITH_DEFAULT(name, Undef, __VA_ARGS__)
69 #if defined(__linux__)
70 #define HILTI_THREAD_LOCAL __thread
72 #define HILTI_THREAD_LOCAL thread_local
78 void internalError(std::string_view msg) __attribute__((noreturn));
82 #undef TINYFORMAT_ERROR
83 #define TINYFORMAT_ERROR(reason) throw ::hilti::rt::FormattingError(reason)
84 #include <hilti/rt/3rdparty/tinyformat/tinyformat.h>
85 #include <hilti/rt/extension-points.h>
86 #include <hilti/rt/fmt.h>
104 uint64_t memory_heap;
107 uint64_t max_fiber_stack_size;
108 uint64_t cached_fibers;
115 extern std::optional<std::string>
getenv(
const std::string& name);
126 hilti::rt::filesystem::path
normalizePath(
const hilti::rt::filesystem::path& p);
133 inline std::string_view
rtrim(std::string_view s,
const std::string& chars) noexcept {
134 s.remove_suffix(s.size() -
135 [](
size_t pos) { return pos != std::string_view::npos ? pos + 1 : 0; }(s.find_last_not_of(chars)));
144 inline std::string_view
ltrim(std::string_view s,
const std::string& chars) noexcept {
145 s.remove_prefix(std::min(s.find_first_not_of(chars), s.size()));
155 inline std::string_view
trim(std::string_view s,
const std::string& chars) noexcept {
160 constexpr
char whitespace_chars[] =
" \t\f\v\n\r";
168 inline std::string_view
rtrim(std::string_view s) noexcept {
return rtrim(s, detail::whitespace_chars); }
175 inline std::string_view
ltrim(std::string_view s) noexcept {
return ltrim(s, detail::whitespace_chars); }
182 inline std::string_view
trim(std::string_view s) noexcept {
return trim(s, detail::whitespace_chars); }
190 std::vector<std::string_view>
split(std::string_view s, std::string_view delim);
197 std::vector<std::string_view>
split(std::string_view s);
205 extern std::pair<std::string, std::string>
split1(std::string s);
213 extern std::pair<std::string, std::string>
rsplit1(std::string s);
221 extern std::pair<std::string, std::string>
split1(std::string s,
const std::string& delim);
229 extern std::pair<std::string, std::string>
rsplit1(std::string s,
const std::string& delim);
236 std::string
replace(std::string s, std::string_view o, std::string_view n);
243 bool startsWith(std::string_view s, std::string_view prefix);
250 bool endsWith(std::string_view s, std::string_view suffix);
256 template<typename T, typename TIter = decltype(std::begin(std::declval<T>())),
257 typename = decltype(std::end(std::declval<T>()))>
262 bool operator!=(
const iterator& other)
const {
return iter != other.iter; }
267 auto operator*()
const {
return std::tie(i, *iter); }
269 struct iterable_wrapper {
271 auto begin() {
return iterator{0, std::begin(iterable)}; }
272 auto end() {
return iterator{0, std::end(iterable)}; }
274 return iterable_wrapper{std::forward<T>(iterable)};
296 std::string expandUTF8Escapes(std::string s);
298 namespace render_style {
308 EscapeQuotes = (1U << 1U),
309 UseOctal = (1U << 2U),
310 NoEscapeBackslash = (1U << 3U),
323 EscapeQuotes = (1U << 1U),
324 NoEscapeBackslash = (1U << 2U),
325 NoEscapeControl = (1U << 3U),
334 enableEnumClassBitmask(hilti::rt::render_style::Bytes);
335 enableEnumClassBitmask(hilti::rt::render_style::UTF8);
348 std::string escapeBytes(std::string_view s, bitmask<render_style::Bytes> style = render_style::Bytes::Default);
360 std::string escapeUTF8(std::string_view s, bitmask<render_style::UTF8> style = render_style::UTF8::Default);
367 std::string
join(
const T& l,
const std::string& delim =
"") {
371 for (
const auto& i : l ) {
374 result += std::string(i);
387 template<
typename T,
typename Allocator>
392 template<
typename C,
typename Y>
393 constexpr
auto transform_result_value(
const C&) {
394 using X =
typename C::value_type;
396 if constexpr ( std::is_same_v<C, std::vector<X>> ) {
397 return std::vector<Y>();
399 else if constexpr ( std::is_same_v<C, std::set<X>> ) {
400 return std::set<Y>();
402 else if constexpr ( is_Vector<C>::value ) {
406 else if constexpr ( std::is_same_v<C, Set<X>> ) {
410 return std::vector<Y>();
416 template<
typename C,
typename F>
418 using Y =
typename std::invoke_result_t<F, typename C::value_type&>;
420 auto y = detail::transform_result_value<C, Y>(x);
421 std::transform(std::begin(x), std::end(x), std::inserter(y, std::end(y)), f);
450 template<
class Iter,
typename Result>
452 if ( base < 2 || base > 36 )
453 throw OutOfRange(
"base for numerical conversion must be between 2 and 36");
456 throw InvalidArgument(
"cannot decode from empty range");
458 std::optional<Result> n = std::nullopt;
466 else if ( *it ==
'+' ) {
471 for ( ; it != e; ++it ) {
475 if ( c >=
'0' && c <
'0' + base )
477 else if ( c >=
'a' && c <
'a' - 10 + base )
479 else if ( c >=
'A' && c <
'A' - 10 + base )
484 n = n.value_or(
Result()) * base + d;
503 template<
typename I1,
typename I2>
504 inline I1
pow(I1 base, I2 exp) {
523 template<
typename T,
typename F, std::size_t... Is>
524 constexpr
auto map_tuple(T&& tup, F& f, std::index_sequence<Is...> ) {
525 return std::make_tuple(f(std::get<Is>(std::forward<T>(tup)))...);
530 template<
typename F, std::size_t I = 0,
typename... Ts>
532 if constexpr ( I ==
sizeof...(Ts) )
535 func(std::get<I>(tup));
536 tuple_for_each<F, I + 1>(tup, func);
544 template<
typename T,
typename F, std::
size_t TupSize = std::tuple_size_v<std::decay_t<T>>>
546 return detail::map_tuple(std::forward<T>(tup), f, std::make_index_sequence<TupSize>{});
550 HILTI_RT_ENUM(ByteOrder, Little, Big,
Network, Host, Undef = -1);
558 namespace detail::adl {
559 std::string
to_string(
const ByteOrder& x, tag );
574 std::string
strftime(
const std::string& format,
const Time& time);
588 Time
strptime(
const std::string& buf,
const std::string& format);
594 const auto tmpdir = hilti::rt::filesystem::temp_directory_path();
595 auto template_ = (tmpdir /
"hilti-rt-test-XXXXXX").native();
596 auto path = ::mkdtemp(template_.data());
598 throw RuntimeError(
"cannot create temporary directory");
610 if ( ! hilti::rt::filesystem::exists(_path, ec) )
614 hilti::rt::filesystem::permissions(_path, hilti::rt::filesystem::perms::all, ec);
620 for (
const auto& entry : hilti::rt::filesystem::recursive_directory_iterator(_path, ec) )
621 hilti::rt::filesystem::permissions(entry, hilti::rt::filesystem::perms::all, ec);
626 hilti::rt::filesystem::remove_all(_path, ec);
629 const auto& path()
const {
return _path; }
633 _path = std::move(other._path);
638 hilti::rt::filesystem::path _path;
642 template<
typename... Hashes>
643 constexpr std::size_t hashCombine(std::size_t hash1, std::size_t hash2, Hashes... hashes) {
644 auto result = hash1 ^ (hash2 << 1);
646 if constexpr (
sizeof...(hashes) > 0 )
647 return hashCombine(result, hashes...);
void tuple_for_each(const std::tuple< Ts... > &tup, F func)
Definition: util.h:531
auto transform(const C &x, F f)
Definition: util.h:417
std::vector< std::string_view > split(std::string_view s, std::string_view delim)
Definition: util.cc:102
constexpr auto enumerate(T &&iterable)
Definition: util.h:258
std::optional< std::string > getenv(const std::string &name)
Definition: util.cc:67
bool endsWith(std::string_view s, std::string_view suffix)
Definition: util.cc:386
hilti::rt::filesystem::path normalizePath(const hilti::rt::filesystem::path &p)
Definition: util.cc:92
Time strptime(const std::string &buf, const std::string &format)
Definition: util.cc:441
void internalError(std::string_view msg) __attribute__((noreturn))
Definition: logging.cc:16
hilti::rt::Result< hilti::rt::filesystem::path > createTemporaryFile(const std::string &prefix="")
Definition: util.cc:74
std::pair< std::string, std::string > split1(std::string s)
Definition: util.cc:146
std::string_view trim(std::string_view s, const std::string &chars) noexcept
Definition: util.h:155
ResourceUsage resource_usage()
Definition: util.cc:43
std::string replace(std::string s, std::string_view o, std::string_view n)
Definition: util.cc:371
std::string strftime(const std::string &format, const Time &time)
Definition: util.cc:415
std::string version()
Definition: util.cc:21
Iter atoi_n(Iter s, Iter e, uint8_t base, Result *result)
Definition: util.h:451
I1 pow(I1 base, I2 exp)
Definition: util.h:504
std::string_view rtrim(std::string_view s, const std::string &chars) noexcept
Definition: util.h:133
void abort_with_backtrace() __attribute__((noreturn))
Definition: util.cc:33
constexpr auto map_tuple(T &&tup, F f)
Definition: util.h:545
std::pair< std::string, std::string > rsplit1(std::string s)
Definition: util.cc:153
std::string_view ltrim(std::string_view s, const std::string &chars) noexcept
Definition: util.h:144
std::string join(const T &l, const std::string &delim="")
Definition: util.h:367
std::string to_string(T &&x)
Definition: extension-points.h:26
ByteOrder systemByteOrder()
Definition: util.cc:393
bool startsWith(std::string_view s, std::string_view prefix)
Definition: util.cc:384
void cannot_be_reached() __attribute__((noreturn))
Definition: util.cc:41