11 #include <initializer_list> 20 #include <type_traits> 21 #include <unordered_map> 25 #include <hilti/rt/filesystem.h> 26 #include <hilti/rt/unpack.h> 27 #include <hilti/rt/util.h> 29 #include <hilti/autogen/config.h> 30 #include <hilti/base/result.h> 34 void __internal_error(
const std::string& s);
37 #undef TINYFORMAT_ERROR 38 #define TINYFORMAT_ERROR(reason) ::util::detail::__internal_error(reason) 39 #include <hilti/rt/3rdparty/tinyformat/tinyformat.h> 50 #define _UNUSED(x) ((void)(x)); 53 #define IF_DERIVED_FROM(t, cls) typename std::enable_if_t<std::is_base_of<cls, t>::value>* = nullptr 56 #define IF_NOT_DERIVED_FROM(t, cls) typename std::enable_if_t<! std::is_base_of<cls, t>::value>* = nullptr 59 #define IF_SAME(t, cls) typename std::enable_if_t<std::is_same<cls, t>::value>* = nullptr 62 #define IF_NOT_SAME(t, cls) typename std::enable_if_t<! std::is_same<cls, t>::value>* = nullptr 74 std::
string typename_() {
79 template<
typename... Args>
80 std::string
fmt(
const char* fmt,
const Args&... args) {
81 return tfm::format(fmt, args...);
87 template<
typename X,
typename F>
88 auto transform_to_vector(
const std::set<X>& x, F f) {
89 using Y =
typename std::invoke_result_t<F, X&>;
92 for (
const auto& i : x )
98 template<
typename C,
typename F>
99 auto filter(
const C& x, F f) {
101 std::copy_if(std::begin(x), std::end(x), std::inserter(y, std::end(y)), f);
109 template<
typename T,
typename TIter = decltype(std::begin(std::declval<T>())),
110 typename = decltype(std::end(std::declval<T>()))>
115 bool operator!=(
const iterator& other)
const {
return iter != other.iter; }
120 auto operator*()
const {
return std::tie(i, *iter); }
122 struct iterable_wrapper {
124 auto begin() {
return iterator{0, std::begin(iterable)}; }
125 auto end() {
return iterator{0, std::end(iterable)}; }
127 return iterable_wrapper{std::forward<T>(iterable)};
131 extern std::vector<std::string>
split(std::string s,
const std::string& delim =
" ");
137 extern std::pair<std::string, std::string>
split1(std::string s,
const std::string& delim =
" ");
143 extern std::pair<std::string, std::string>
rsplit1(std::string s,
const std::string& delim =
" ");
154 std::vector<T> slice(
const std::vector<T>& v,
int begin,
int end = -1) {
156 begin = v.size() + begin;
158 if ( static_cast<size_t>(begin) > v.size() )
162 end = v.size() + end + 1;
170 if ( static_cast<size_t>(end) > v.size() )
173 return std::vector<T>(v.begin() + begin, v.begin() + end);
181 std::string
join(
const T& l,
const std::string& delim =
"") {
185 for (
const auto& i : l ) {
189 result += std::string(i);
201 std::string
join(
const std::initializer_list<T>& l,
const std::string& delim =
"") {
205 for (
const auto& i : l ) {
208 result += std::string(i);
219 template<
typename iterator>
220 std::string
join(
const iterator& begin,
const iterator& end,
const std::string& delim =
"") {
224 for ( iterator i = begin; i != end; i++ ) {
227 result += std::string(*i);
252 extern std::string prefixParts(
const std::string& in,
const std::string& prefix,
const std::string& include_tag =
"");
264 extern std::vector<std::string> flattenParts(
const std::vector<std::string>& in);
267 extern std::string
replace(
const std::string& s,
const std::string& o,
const std::string& n);
270 extern std::string tolower(
const std::string& s);
273 extern std::string toupper(
const std::string& s);
276 extern std::string
trim(
const std::string& s);
279 extern std::string
rtrim(
const std::string& s);
282 extern std::string
ltrim(
const std::string& s);
285 inline bool startsWith(
const std::string& s,
const std::string& prefix) {
return s.find(prefix) == 0; }
288 extern bool endsWith(
const std::string& s,
const std::string& suffix);
291 extern uint64_t hash(
const std::string& str);
294 extern uint64_t hash(
const char* data,
size_t len);
300 constexpr std::pair<intmax_t, intmax_t> signed_integer_range(
int width) {
302 case 8:
return std::make_pair(INT8_MIN, INT8_MAX);
303 case 16:
return std::make_pair(INT16_MIN, INT16_MAX);
304 case 32:
return std::make_pair(INT32_MIN, INT32_MAX);
305 case 64:
return std::make_pair(INT64_MIN, INT64_MAX);
306 default:
throw std::out_of_range(
"unsupported integer width");
314 constexpr std::pair<uintmax_t, uintmax_t> unsigned_integer_range(
int width) {
316 case 8:
return std::make_pair(0, UINT8_MAX);
317 case 16:
return std::make_pair(0, UINT16_MAX);
318 case 32:
return std::make_pair(0, UINT32_MAX);
319 case 64:
return std::make_pair(0, UINT64_MAX);
320 default:
throw std::out_of_range(
"unsupported integer width");
331 template<
typename Error>
332 uint64_t chars_to_uint64(
const char* dgts,
int base, Error handler) {
335 auto u = strtoull(dgts, &cp, base);
336 if ( cp == dgts || *cp !=
'\0' || (u == ULONG_MAX && errno == ERANGE) ) {
349 template<
typename Error>
350 double chars_to_double(
const char* dgts, Error handler) {
353 auto d = strtod(dgts, &cp);
354 if ( cp == dgts || *cp !=
'\0' || (d == HUGE_VAL && errno == ERANGE) ) {
372 extern std::string uitoa_n(uint64_t value,
unsigned int base,
int n = -1);
374 using hilti::rt::escapeBytes;
375 using hilti::rt::escapeUTF8;
376 using hilti::rt::expandEscapes;
385 inline std::string escapeBytesForCxx(std::string_view s) {
return escapeBytes(s,
true,
true); }
396 extern std::string toIdentifier(
const std::string& s,
bool ensure_non_keyword =
false);
399 extern double currentTime();
403 const std::vector<hilti::rt::filesystem::path>& paths);
417 hilti::rt::filesystem::path currentExecutable();
423 template<
class Iter,
typename Result>
424 inline auto atoi_n(Iter s, Iter e,
int base, Result* result) {
433 template<
typename A,
typename B>
434 std::list<std::pair<A, B>> zip2(
const std::list<A>& lhs,
const std::list<B>& rhs) {
435 std::list<std::pair<A, B>> result;
436 for ( std::pair<
typename std::list<A>::const_iterator,
typename std::list<B>::const_iterator> iter =
437 std::pair<
typename std::list<A>::const_iterator,
typename std::list<B>::const_iterator>(lhs.cbegin(),
439 iter.first != lhs.end() and iter.second != rhs.end(); ++iter.first, ++iter.second )
440 result.emplace_back(*iter.first, *iter.second);
449 template<
typename A,
typename B>
450 std::vector<std::pair<A, B>> zip2(
const std::vector<A>& lhs,
const std::vector<B>& rhs) {
451 std::vector<std::pair<A, B>> result;
452 for ( std::pair<
typename std::vector<A>::const_iterator,
typename std::vector<B>::const_iterator> iter =
453 std::pair<
typename std::vector<A>::const_iterator,
typename std::vector<B>::const_iterator>(lhs.cbegin(),
455 iter.first != lhs.end() and iter.second != rhs.end(); ++iter.first, ++iter.second )
456 result.emplace_back(*iter.first, *iter.second);
461 template<
typename A,
typename B>
462 std::set<A> map_keys(
const std::map<A, B>& m) {
465 for (
const auto& i : m )
472 template<
typename A,
typename B>
473 std::set<B> map_values(
const std::map<A, B>& m) {
476 for (
const auto& i : m )
483 template<
typename A,
typename B>
484 std::set<A> map_keys(
const std::unordered_map<A, B>& m) {
487 for (
const auto& i : m )
494 template<
typename A,
typename B>
495 std::set<B> map_values(
const std::unordered_map<A, B>& m) {
498 for (
const auto& i : m )
505 template<
typename A,
typename Compare = std::less<A>>
506 std::set<A, Compare> set_difference(
const std::set<A, Compare>& a,
const std::set<A, Compare>& b) {
507 std::set<A, Compare> r;
508 std::set_difference(a.begin(), a.end(), b.begin(), b.end(), std::inserter(r, r.end()), Compare());
513 template<
typename A,
typename Compare = std::less<A>>
514 std::set<A, Compare> set_intersection(std::set<A, Compare>& a, std::set<A, Compare>& b) {
515 std::set<A, Compare> r;
516 std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::inserter(r, r.end()), Compare());
521 template<
typename A,
typename Compare = std::less<A>>
522 std::set<A, Compare> set_union(
const std::set<A, Compare>& a,
const std::set<A, Compare>& b) {
523 std::set<A, Compare> r;
524 std::set_union(a.begin(), a.end(), b.begin(), b.end(), std::inserter(r, r.end()), Compare());
530 std::vector<T> concat(std::vector<T> v1,
const std::vector<T>& v2) {
531 v1.reserve(v1.size() + v2.size());
532 v1.insert(v1.end(), v2.begin(), v2.end());
538 std::vector<T>& append(std::vector<T>& v1,
const std::vector<T>& v2) {
539 v1.reserve(v1.size() + v2.size());
540 v1.insert(v1.end(), v2.begin(), v2.end());
546 std::vector<T> remove_duplicates(std::vector<T> v) {
550 for (
auto&& i : v ) {
551 if ( seen.find(i) != seen.end() )
555 out.emplace_back(std::move(i));
567 std::string uniqueIndex(
const T& c, std::string hint) {
568 if ( c.find(hint) == c.end() )
575 std::string idx =
fmt(
"%s.%d", hint, ++cnt);
576 if ( c.find(idx) == c.end() )
582 inline bool copyStream(std::istream& in, std::ostream& out) {
584 while ( in.good() ) {
585 in.read(buffer,
sizeof(buffer));
586 out.write(buffer,
sizeof(buffer));
611 template<
typename Enum, std::
size_t Size>
612 constexpr
auto from_string(
const std::string_view name,
const Value<Enum> (&values)[Size]) {
613 for (
const auto& v : values )
614 if ( v.name == name )
617 throw std::out_of_range(name.data());
630 template<
typename Enum, std::
size_t Size>
631 constexpr
auto to_string(Enum value,
const Value<Enum> (&values)[Size]) {
632 for (
const auto& v : values )
633 if ( v.value == value )
636 throw std::out_of_range(std::to_string(static_cast<int>(value)));
647 std::optional<hilti::rt::filesystem::path> cacheDirectory(
const hilti::Configuration& configuration);
auto transform(const C &x, F f)
Definition: util.h:362
auto filter(const hilti::node::Range< X > &x, F f)
Definition: node.h:884
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
Definition: optional.h:79
std::string demangle(const std::string &symbol)
Definition: backtrace.h:40
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::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: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
void abort_with_backtrace() __attribute__((noreturn))
Definition: util.cc:34
std::string_view trim(std::string_view s, const std::string &chars) noexcept
Definition: util.h:143
std::string fmt(const char *fmt, const Args &... args)
Definition: fmt.h:13