0.6.0
C++ to UML diagram generator based on Clang
Loading...
Searching...
No Matches
Classes | Functions | Variables
clanguml::util Namespace Reference

Detailed Description

src/util/memoized.h

Copyright (c) 2021-2025 Bartek Kryza bkryz.nosp@m.a@gm.nosp@m.ail.c.nosp@m.om

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Classes

class  memoized
 Simple memoization implementation for expensive methods. More...
 
class  memoized< T, Ret >
 
class  memoized< T, Ret, bool >
 
class  query_driver_output_extractor
 Executed compiler frontend and extract default system paths. More...
 
class  thread_pool_executor
 Simple thread pool executor for parallelizing diagram generation. More...
 

Functions

std::string get_process_output (const std::string &command)
 Execute a shell command and return console output as string.
 
void check_process_output (const std::string &command)
 Execute command shell and throw exception if command fails.
 
std::string get_env (const std::string &name)
 Get value of an environment variable.
 
bool is_git_repository ()
 Check if $PWD is in a Git repository.
 
std::string run_git_command (const std::string &cmd, const std::string &env_override)
 
std::string get_git_branch ()
 Get current Git branch.
 
std::string get_git_revision ()
 Get current Git revision.
 
std::string get_git_commit ()
 Get current Git commit.
 
std::string get_git_toplevel_dir ()
 Get path to the top level Git directory.
 
std::string get_os_name ()
 Get descriptive name of the current operating system.
 
std::string ltrim (const std::string &s)
 Left trim a string.
 
std::string rtrim (const std::string &s)
 Right trim a string.
 
std::string trim_typename (const std::string &s)
 Remove typename prefix from a string if exists.
 
std::string trim (const std::string &s)
 Trim a string.
 
std::optional< std::pair< std::string, std::string > > split_at_first (const std::string &separator, const std::string &input)
 Split string at first occurence of separator.
 
std::vector< std::string > split (std::string str, std::string_view delimiter, bool skip_empty=true)
 Split a string using delimiter.
 
std::vector< std::string > split_isspace (std::string str)
 
std::string join (const std::vector< std::string > &toks, std::string_view delimiter)
 Join toks into string using delimiter as separator.
 
std::string abbreviate (const std::string &s, unsigned int max_length)
 Abbreviate string to max_length, and replace last 3 characters with ellipsis.
 
bool find_element_alias (const std::string &input, std::tuple< std::string, size_t, size_t > &result)
 Find element alias in Puml note.
 
bool replace_all (std::string &input, const std::string &pattern, const std::string &replace_with)
 Find and replace in string.
 
template<>
bool starts_with (const std::string &s, const std::string &prefix)
 
template<>
bool ends_with (const std::string &value, const std::string &suffix)
 
std::size_t hash_seed (std::size_t seed)
 Generate a hash seed.
 
std::string path_to_url (const std::filesystem::path &p)
 Convert filesystem path to url path.
 
std::filesystem::path ensure_path_is_absolute (const std::filesystem::path &p, const std::filesystem::path &root=std::filesystem::current_path())
 Ensure path is absolute.
 
bool is_relative_to (const std::filesystem::path &parent, const std::filesystem::path &child)
 Check if a given path is relative to another path.
 
std::string format_message_comment (const std::string &comment, unsigned width)
 
std::optional< std::pair< std::string, std::string > > find_entry_by_path_prefix (const std::map< std::string, std::string > &m, const std::string &path)
 
template<typename T , typename S >
std::unique_ptr< T > unique_pointer_cast (std::unique_ptr< S > &&p) noexcept
 
template<typename T , typename F >
void erase_if (std::vector< T > &v, F &&f)
 Remove and erase elements from a vector.
 
template<typename... Args>
std::string join (std::string_view delimiter, Args... args)
 Join args into string using delimiter as separator.
 
template<typename T >
void append (std::vector< T > &l, const std::vector< T > &r)
 Appends a vector to a vector.
 
template<typename T >
bool starts_with (const T &col, const T &prefix)
 Checks if collection starts with a prefix.
 
template<>
bool starts_with (const std::string &s, const std::string &prefix)
 
template<typename T >
bool ends_with (const T &value, const T &suffix)
 
template<>
bool ends_with (const std::string &value, const std::string &suffix)
 
template<typename T >
bool ends_with (const std::vector< T > &col, const std::vector< T > &suffix)
 
template<typename T >
void remove_prefix (std::vector< T > &col, const std::vector< T > &prefix)
 Removes prefix sequence of elements from the beginning of col.
 
template<typename T , typename E >
bool contains (const T &container, const E &element)
 
template<typename T , typename F >
void for_each (const T &collection, F &&func)
 
template<typename R , typename T , typename F >
std::vector< R > map (const std::vector< T > &in, F &&f)
 
template<typename T , typename F , typename FElse >
void if_not_null (const T *pointer, F &&func, FElse &&func_else)
 
template<typename T , typename F >
void if_not_null (const T *pointer, F &&func)
 
template<typename F , typename FElse >
void _if (const bool condition, F &&func, FElse &&func_else)
 
template<typename F >
void _if (const bool condition, F &&func)
 
template<typename T >
void remove_duplicates (T &coll)
 

Variables

static const auto WHITESPACE = " \n\r\t\f\v"
 
constexpr unsigned kDefaultMessageCommentWidth {25U}
 

Function Documentation

◆ _if() [1/2]

template<typename F >
void clanguml::util::_if ( const bool  condition,
F &&  func 
)

Definition at line 379 of file util.h.

380{
381 _if(condition, std::forward<F>(func), []() {});
382}

◆ _if() [2/2]

template<typename F , typename FElse >
void clanguml::util::_if ( const bool  condition,
F &&  func,
FElse &&  func_else 
)

Definition at line 369 of file util.h.

370{
371 if (condition) {
372 std::forward<F>(func)();
373 }
374 else {
375 std::forward<FElse>(func_else)();
376 }
377}

◆ abbreviate()

std::string clanguml::util::abbreviate ( const std::string &  s,
unsigned int  max_length 
)

Abbreviate string to max_length, and replace last 3 characters with ellipsis.

Parameters
sInput string
max_lengthMaximum length
Returns
Abbreviated string

Definition at line 333 of file util.cc.

334{
335 if (s.size() <= max_length)
336 return s;
337
338 auto res = s;
339
340 res.resize(max_length);
341
342 if (res.size() > 3) {
343 res.replace(res.size() - 3, 3, 3, '.');
344 }
345
346 return res;
347}

◆ append()

template<typename T >
void clanguml::util::append ( std::vector< T > &  l,
const std::vector< T > &  r 
)

Appends a vector to a vector.

Template Parameters
T
Parameters
l
r

Definition at line 257 of file util.h.

258{
259 l.insert(l.end(), r.begin(), r.end());
260}

◆ check_process_output()

void clanguml::util::check_process_output ( const std::string &  command)

Execute command shell and throw exception if command fails.

Parameters
commandCommand to execute

Definition at line 97 of file util.cc.

98{
99 constexpr size_t kBufferSize{1024};
100 std::array<char, kBufferSize> buffer{};
101 int result{EXIT_FAILURE};
102 std::string output;
103 pipe_t pipe{command, result};
104
105 if (!pipe) {
106 throw std::runtime_error("popen() failed!");
107 }
108
109 while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
110 output += buffer.data();
111 }
112
113 pipe.reset();
114
115 if (result != EXIT_SUCCESS) {
116 throw std::runtime_error(
117 fmt::format("External command '{}' failed: {}", command, output));
118 }
119}

◆ contains()

template<typename T , typename E >
bool clanguml::util::contains ( const T &  container,
const E &  element 
)

Returns true if element exists in container.

Template Parameters
T
E
Parameters
container
element
Returns

Definition at line 321 of file util.h.

322{
323 if constexpr (std::is_pointer_v<E>) {
324 return std::find_if(container.begin(), container.end(),
325 [&element](const auto &e) { return *e == *element; }) !=
326 container.end();
327 }
328 else if constexpr (std::is_same_v<std::remove_cv_t<T>, std::string>) {
329 return container.find(element) != std::string::npos;
330 }
331 else {
332 return std::find(container.begin(), container.end(), element) !=
333 container.end();
334 }
335}

◆ ends_with() [1/4]

template<>
bool clanguml::util::ends_with ( const std::string &  value,
const std::string &  suffix 
)

Definition at line 391 of file util.cc.

392{
393 if (suffix.size() > value.size())
394 return false;
395 return std::equal(suffix.rbegin(), suffix.rend(), value.rbegin());
396}

◆ ends_with() [2/4]

template<>
bool clanguml::util::ends_with ( const std::string &  value,
const std::string &  suffix 
)

Definition at line 391 of file util.cc.

392{
393 if (suffix.size() > value.size())
394 return false;
395 return std::equal(suffix.rbegin(), suffix.rend(), value.rbegin());
396}

◆ ends_with() [3/4]

template<typename T >
bool clanguml::util::ends_with ( const std::vector< T > &  col,
const std::vector< T > &  suffix 
)

Definition at line 286 of file util.h.

287{
288 if (suffix.size() > col.size())
289 return false;
290
291 return std::vector<std::string>(suffix.rbegin(), suffix.rend()) ==
292 std::vector<std::string>(col.rbegin(), col.rbegin() + suffix.size());
293}

◆ ends_with() [4/4]

template<typename T >
bool clanguml::util::ends_with ( const T &  value,
const T &  suffix 
)

◆ ensure_path_is_absolute()

std::filesystem::path clanguml::util::ensure_path_is_absolute ( const std::filesystem::path &  p,
const std::filesystem::path &  root = std::filesystem::current_path() 
)

Ensure path is absolute.

If path is absolute, return the p. If path is not absolute, make it absolute with respect to root directory.

Parameters
pPath to modify
rootRoot against which the path should be made absolute
Returns
Absolute path

Definition at line 435 of file util.cc.

437{
438 if (p.is_absolute())
439 return p;
440
441 auto result = root / p;
442 result = result.lexically_normal();
443 result.make_preferred();
444
445 return result;
446}

◆ erase_if()

template<typename T , typename F >
void clanguml::util::erase_if ( std::vector< T > &  v,
F &&  f 
)

Remove and erase elements from a vector.

Template Parameters
TElement type
FFunctor type
Parameters
vVector to remove elements from
fFunctor to decide which elements to remove

Definition at line 182 of file util.h.

183{
184 v.erase(std::remove_if(v.begin(), v.end(), std::forward<F>(f)), v.end());
185}

◆ find_element_alias()

bool clanguml::util::find_element_alias ( const std::string &  input,
std::tuple< std::string, size_t, size_t > &  result 
)

Find element alias in Puml note.

Finds aliases of the form (entity_name) in the Puml notes or directives. The match, if any, is returned in the result tuple: (entity_name, offset, length)

Returns
True if match was found

Definition at line 349 of file util.cc.

351{
352 const std::regex alias_regex(R"((@A\‍([^\).]+\)))");
353
354 auto alias_it =
355 std::sregex_iterator(input.begin(), input.end(), alias_regex);
356 auto end_it = std::sregex_iterator();
357
358 if (alias_it == end_it)
359 return false;
360
361 const std::smatch &match = *alias_it;
362 const std::string alias = match.str().substr(3, match.str().size() - 4);
363
364 std::get<0>(result) = alias;
365 std::get<1>(result) = match.position();
366 std::get<2>(result) = match.length();
367
368 return true;
369}

◆ find_entry_by_path_prefix()

std::optional< std::pair< std::string, std::string > > clanguml::util::find_entry_by_path_prefix ( const std::map< std::string, std::string > &  m,
const std::string &  path 
)

Definition at line 500 of file util.cc.

502{
503 if (m.empty())
504 return {};
505
506 // Extract keys and sort them by length in descending order
507 std::vector<std::string> keys;
508 keys.reserve(m.size());
509 for (const auto &[key, pattern] : m) {
510 keys.push_back(key);
511 }
512
513 std::sort(keys.begin(), keys.end(),
514 [](const std::string &a, const std::string &b) {
515 return a.size() > b.size();
516 });
517
518 std::filesystem::path file_path{path};
519
520 for (const auto &key : keys) {
521 const auto &pattern = m.at(key);
522 std::filesystem::path key_path{key};
523
524 if (is_relative_to(file_path, key_path)) {
525 return {{key, pattern}};
526 }
527 }
528
529 if ((path.empty() || file_path.is_relative() || path == ".") &&
530 m.count(".") > 0) {
531 return {{".", m.at(".")}};
532 }
533
534 return {};
535}

◆ for_each()

template<typename T , typename F >
void clanguml::util::for_each ( const T &  collection,
F &&  func 
)

Definition at line 337 of file util.h.

338{
339 std::for_each(std::begin(collection), std::end(collection),
340 std::forward<decltype(func)>(func));
341}

◆ format_message_comment()

std::string clanguml::util::format_message_comment ( const std::string &  comment,
unsigned  width 
)

Definition at line 464 of file util.cc.

465{
466 if (width == 0)
467 return comment;
468
469 std::string result;
470
471 if (comment.empty())
472 return result;
473
474 auto tokens = split_isspace(comment);
475
476 if (tokens.empty())
477 return result;
478
479 unsigned current_line_length{0};
480 for (const auto &token : tokens) {
481 if (current_line_length < width) {
482 result += token;
483 result += ' ';
484 }
485 else {
486 result.back() = '\n';
487 current_line_length = 0;
488 result += token;
489 result += ' ';
490 }
491
492 current_line_length += token.size() + 1;
493 }
494
495 result.pop_back();
496
497 return result;
498}

◆ get_env()

std::string clanguml::util::get_env ( const std::string &  name)

Get value of an environment variable.

Parameters
nameName of the environment variable
Returns
Value of the environment variable, or empty if it doesn't exist

Definition at line 121 of file util.cc.

122{
123#if defined(__linux) || defined(__unix)
124 const char *value = std::getenv(name.c_str()); // NOLINT
125
126 if (value == nullptr)
127 return {};
128
129 return std::string{value};
130#elif defined(WINDOWS) || defined(_WIN32) || defined(WIN32)
131 static constexpr auto kMaxEnvLength = 2096U;
132 static char value[kMaxEnvLength];
133 const DWORD ret =
134 GetEnvironmentVariableA(name.c_str(), value, kMaxEnvLength);
135 if (ret == 0 || ret > kMaxEnvLength)
136 return {};
137 else
138 return value;
139#else
140 return {};
141#endif
142}

◆ get_git_branch()

std::string clanguml::util::get_git_branch ( )

Get current Git branch.

Returns
Name of the current Git branch

Definition at line 183 of file util.cc.

184{
185 return run_git_command(
186 "git rev-parse --abbrev-ref HEAD", "CLANGUML_GIT_BRANCH");
187}

◆ get_git_commit()

std::string clanguml::util::get_git_commit ( )

Get current Git commit.

Returns
Latest Git commit hash

Definition at line 195 of file util.cc.

196{
197 return run_git_command("git rev-parse HEAD", "CLANGUML_GIT_COMMIT");
198}

◆ get_git_revision()

std::string clanguml::util::get_git_revision ( )

Get current Git revision.

Generates a Git revision tag using git describe --tags --always command

Returns
Current repository Git revision

Definition at line 189 of file util.cc.

190{
191 return run_git_command(
192 "git describe --tags --always", "CLANGUML_GIT_REVISION");
193}

◆ get_git_toplevel_dir()

std::string clanguml::util::get_git_toplevel_dir ( )

Get path to the top level Git directory.

Returns
Absolut path to the nearest directory containing .git folder

Definition at line 200 of file util.cc.

201{
202 return run_git_command(
203 "git rev-parse --show-toplevel", "CLANGUML_GIT_TOPLEVEL_DIR");
204}

◆ get_os_name()

std::string clanguml::util::get_os_name ( )

Get descriptive name of the current operating system.

Returns
Name of the operating system

Definition at line 206 of file util.cc.

207{
208#ifdef _WIN32
209 return "Windows, 32-bit";
210#elif _WIN64
211 return "Windows, 64-bit";
212#elif __has_include(<sys/utsname.h>)
213 struct utsname utsn; // NOLINT
214 uname(&utsn);
215 return fmt::format("{} {} {}", utsn.sysname, utsn.machine, utsn.release);
216#elif __linux__
217 return "Linux";
218#elif __APPLE__ || __MACH__
219 return "macOS";
220#elif __FreeBSD__
221 return "FreeBSD";
222#elif __unix__ || __unix
223 return "Unix";
224#else
225 return "Unknown";
226#endif
227}

◆ get_process_output()

std::string clanguml::util::get_process_output ( const std::string &  command)

Execute a shell command and return console output as string.

Parameters
commandShell command to execute
Returns
Console output of the command

Definition at line 70 of file util.cc.

71{
72 constexpr size_t kBufferSize{1024};
73 std::array<char, kBufferSize> buffer{};
74 std::string output;
75 int result{EXIT_FAILURE};
76
77 pipe_t pipe{command, result};
78
79 if (!pipe) {
80 throw std::runtime_error("popen() failed!");
81 }
82
83 while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
84 output += buffer.data();
85 }
86
87 pipe.reset();
88
89 if (result != EXIT_SUCCESS) {
90 throw std::runtime_error(
91 fmt::format("External command '{}' failed: {}", command, output));
92 }
93
94 return output;
95}

◆ hash_seed()

std::size_t clanguml::util::hash_seed ( std::size_t  seed)

Generate a hash seed.

Parameters
seedInitial seed.
Returns
Hash seed.

Definition at line 398 of file util.cc.

399{
400 constexpr auto kSeedStart{0x6a3712b5};
401 constexpr auto kSeedShiftFirst{6};
402 constexpr auto kSeedShiftSecond{2};
403
404 return kSeedStart + (seed << kSeedShiftFirst) + (seed >> kSeedShiftSecond);
405}

◆ if_not_null() [1/2]

template<typename T , typename F >
void clanguml::util::if_not_null ( const T *  pointer,
F &&  func 
)

Definition at line 363 of file util.h.

364{
365 if_not_null(pointer, std::forward<F>(func), []() {});
366}

◆ if_not_null() [2/2]

template<typename T , typename F , typename FElse >
void clanguml::util::if_not_null ( const T *  pointer,
F &&  func,
FElse &&  func_else 
)

Definition at line 353 of file util.h.

354{
355 if (pointer != nullptr) {
356 std::forward<F>(func)(pointer);
357 }
358 else {
359 std::forward<FElse>(func_else)();
360 }
361}

◆ is_git_repository()

bool clanguml::util::is_git_repository ( )

Check if $PWD is in a Git repository.

This can be overridden by exporting CLANGUML_GIT_COMMIT environment variable.

Returns
True, if the current directory is in a Git repository

Definition at line 144 of file util.cc.

145{
146 const auto env = get_env("CLANGUML_GIT_COMMIT");
147
148 if (!env.empty())
149 return true;
150
151 std::string output;
152
153 try {
154 output = get_process_output("git rev-parse --git-dir");
155 }
156 catch (std::runtime_error &e) {
157 return false;
158 }
159
160 return contains(trim(output), ".git");
161}

◆ is_relative_to()

bool clanguml::util::is_relative_to ( const std::filesystem::path &  parent,
const std::filesystem::path &  child 
)

Check if a given path is relative to another path.

Parameters
parentThe path to be checked for relativity.
rightThe base path against which the relativity is checked.
Returns
True if the child path is relative to the parent path, false otherwise.

Definition at line 448 of file util.cc.

450{
451 if (child.has_root_directory() != base.has_root_directory())
452 return false;
453
454 const auto child_ln = child.lexically_normal();
455 const auto base_ln = base.lexically_normal();
456
457 if (child_ln == base_ln)
458 return true;
459
460 auto rel = child_ln.lexically_relative(base_ln);
461 return !rel.empty() && rel.native()[0] != '.';
462}

◆ join() [1/2]

std::string clanguml::util::join ( const std::vector< std::string > &  toks,
std::string_view  delimiter 
)

Join toks into string using delimiter as separator.

Parameters
toksElements to join into string
delimiterSeparator to use to join elements
Returns
Concatenated elements into one string

Definition at line 327 of file util.cc.

329{
330 return fmt::format("{}", fmt::join(toks, delimiter));
331}

◆ join() [2/2]

template<typename... Args>
std::string clanguml::util::join ( std::string_view  delimiter,
Args...  args 
)

Join args into string using delimiter as separator.

Template Parameters
ArgsElement type
Parameters
delimiterSeparator to use to join elements
argsElements to join into string
Returns
Arguments concatenated into one string

Definition at line 206 of file util.h.

207{
208 std::vector<std::string> coll{args...};
209
210 erase_if(coll, [](const auto &s) {
211 return s.find_first_not_of(" \t") == std::string::npos;
212 });
213
214 return fmt::format("{}", fmt::join(coll, delimiter));
215}

◆ ltrim()

std::string clanguml::util::ltrim ( const std::string &  s)

Left trim a string.

Parameters
sInput string
Returns
Left trimmed string

Definition at line 229 of file util.cc.

230{
231 const size_t start = s.find_first_not_of(WHITESPACE);
232 return (start == std::string::npos) ? "" : s.substr(start);
233}

◆ map()

template<typename R , typename T , typename F >
std::vector< R > clanguml::util::map ( const std::vector< T > &  in,
F &&  f 
)

Definition at line 344 of file util.h.

345{
346 std::vector<R> out;
347 std::transform(
348 in.cbegin(), in.cend(), std::back_inserter(out), std::forward<F>(f));
349 return out;
350}

◆ path_to_url()

std::string clanguml::util::path_to_url ( const std::filesystem::path &  p)

Convert filesystem path to url path.

The purpose of this function is to make sure that a path can be used in a URL, e.g. it's separators are POSIX-style.

Parameters
pPath to convert
Returns
String representation of the path in URL format

Definition at line 407 of file util.cc.

408{
409 std::vector<std::string> path_tokens;
410 auto it = p.begin();
411 if (p.has_root_directory()) {
412#ifdef _MSC_VER
413 // On Windows convert the root path using its drive letter, e.g.:
414 // C:\A\B\include.h -> /c/A/B/include.h
415 if (p.root_name().string().size() > 1) {
416 if (p.is_absolute()) {
417 path_tokens.push_back(std::string{
418 std::tolower(p.root_name().string().at(0), std::locale())});
419 }
420 it++;
421 }
422#endif
423 it++;
424 }
425
426 for (; it != p.end(); it++)
427 path_tokens.push_back(it->string());
428
429 if (p.has_root_directory())
430 return fmt::format("/{}", fmt::join(path_tokens, "/"));
431
432 return fmt::format("{}", fmt::join(path_tokens, "/"));
433}

◆ remove_duplicates()

template<typename T >
void clanguml::util::remove_duplicates ( T &  coll)

Definition at line 384 of file util.h.

385{
386 std::sort(coll.begin(), coll.end());
387 coll.erase(std::unique(coll.begin(), coll.end()), coll.end());
388}

◆ remove_prefix()

template<typename T >
void clanguml::util::remove_prefix ( std::vector< T > &  col,
const std::vector< T > &  prefix 
)

Removes prefix sequence of elements from the beginning of col.

Template Parameters
T
Parameters
col
prefix

Definition at line 303 of file util.h.

304{
305 if (!starts_with(col, prefix))
306 return;
307
308 col = std::vector<T>(col.begin() + prefix.size(), col.end());
309}

◆ replace_all()

bool clanguml::util::replace_all ( std::string &  input,
const std::string &  pattern,
const std::string &  replace_with 
)

Find and replace in string.

Replaces all occurences of pattern with replace_with in input string.

Returns
True if at least on replacement was made

Definition at line 371 of file util.cc.

373{
374 bool replaced{false};
375
376 auto pos = input.find(pattern);
377 while (pos < input.size()) {
378 input.replace(pos, pattern.size(), replace_with);
379 pos = input.find(pattern, pos + replace_with.size());
380 replaced = true;
381 }
382
383 return replaced;
384}

◆ rtrim()

std::string clanguml::util::rtrim ( const std::string &  s)

Right trim a string.

Parameters
sInput string
Returns
Right trimmed string

Definition at line 235 of file util.cc.

236{
237 const size_t end = s.find_last_not_of(WHITESPACE);
238 return (end == std::string::npos) ? "" : s.substr(0, end + 1);
239}

◆ run_git_command()

std::string clanguml::util::run_git_command ( const std::string &  cmd,
const std::string &  env_override 
)

Definition at line 163 of file util.cc.

165{
166 auto env = get_env(env_override);
167
168 if (!env.empty())
169 return env;
170
171 std::string output;
172
173 try {
174 output = get_process_output(cmd);
175 }
176 catch (std::runtime_error &e) {
177 return {};
178 }
179
180 return trim(output);
181}

◆ split()

std::vector< std::string > clanguml::util::split ( std::string  str,
std::string_view  delimiter,
bool  skip_empty = true 
)

Split a string using delimiter.

Basic string split function, because C++ stdlib does not have one. In case the string does not contain the delimiter, the original string is returned as the only element of the vector.

Parameters
strString to split
delimiterDelimiter string
skip_emptySkip empty toks between delimiters if true
Returns
Vector of string tokens.

Definition at line 270 of file util.cc.

272{
273 std::vector<std::string> result;
274
275 if (!contains(str, delimiter)) {
276 if (!str.empty())
277 result.push_back(std::move(str));
278 else if (!skip_empty)
279 result.push_back(std::move(str));
280 }
281 else
282 while (static_cast<unsigned int>(!str.empty()) != 0U) {
283 auto index = str.find(delimiter);
284 if (index != std::string::npos) {
285 auto tok = str.substr(0, index);
286 if (!tok.empty())
287 result.push_back(std::move(tok));
288 else if (!skip_empty)
289 result.push_back(std::move(tok));
290
291 str = str.substr(index + delimiter.size());
292 }
293 else {
294 if (!str.empty())
295 result.push_back(std::move(str));
296 else if (!skip_empty)
297 result.push_back(std::move(str));
298 str = "";
299 }
300 }
301
302 return result;
303}

◆ split_at_first()

std::optional< std::pair< std::string, std::string > > clanguml::util::split_at_first ( const std::string &  separator,
const std::string &  input 
)

Split string at first occurence of separator.

Parameters
separator
input
Returns
Elements from

Definition at line 252 of file util.cc.

254{
255 std::optional<std::pair<std::string, std::string>> res;
256
257 std::size_t pos = input.find(separator);
258
259 if (pos == std::string::npos) {
260 return res;
261 }
262
263 auto before = input.substr(0, pos);
264 auto after = input.substr(pos + separator.size());
265
266 return std::make_optional<std::pair<std::string, std::string>>(
267 std::move(before), std::move(after));
268}

◆ split_isspace()

std::vector< std::string > clanguml::util::split_isspace ( std::string  str)

Definition at line 305 of file util.cc.

306{
307 std::vector<std::string> result;
308
309 while (static_cast<unsigned int>(!str.empty()) != 0U) {
310 auto index = std::find_if(
311 str.begin(), str.end(), [](auto c) { return std::isspace(c); });
312 if (index != str.end()) {
313 auto tok = str.substr(0, std::distance(str.begin(), index));
314 if (!tok.empty())
315 result.push_back(std::move(tok));
316 str = str.substr(std::distance(str.begin(), index) + 1);
317 }
318 else {
319 if (!str.empty())
320 result.push_back(str);
321 str = "";
322 }
323 }
324 return result;
325}

◆ starts_with() [1/3]

template<>
bool clanguml::util::starts_with ( const std::string &  s,
const std::string &  prefix 
)

Definition at line 386 of file util.cc.

387{
388 return s.rfind(prefix, 0) == 0;
389}

◆ starts_with() [2/3]

template<>
bool clanguml::util::starts_with ( const std::string &  s,
const std::string &  prefix 
)

Definition at line 386 of file util.cc.

387{
388 return s.rfind(prefix, 0) == 0;
389}

◆ starts_with() [3/3]

template<typename T >
bool clanguml::util::starts_with ( const T &  col,
const T &  prefix 
)

Checks if collection starts with a prefix.

Template Parameters
Te.g. std::vector<std::string>
Parameters
colCollection to be checked against prefix
prefixContainer, which specifies the prefix
Returns
true if first prefix.size() elements of col are equal to prefix

Definition at line 270 of file util.h.

271{
272 if (prefix.size() > col.size())
273 return false;
274
275 return std::search(col.begin(), col.end(), prefix.begin(), prefix.end()) ==
276 col.begin();
277}

◆ trim()

std::string clanguml::util::trim ( const std::string &  s)

Trim a string.

Parameters
sInput string
Returns
Trimmed string

Definition at line 250 of file util.cc.

250{ return rtrim(ltrim(s)); }

◆ trim_typename()

std::string clanguml::util::trim_typename ( const std::string &  s)

Remove typename prefix from a string if exists.

Parameters
sInput string
Returns
String without typename prefix

Definition at line 241 of file util.cc.

242{
243 auto res = trim(s);
244 if (res.find("typename ") == 0)
245 return res.substr(strlen("typename "));
246
247 return res;
248}

◆ unique_pointer_cast()

template<typename T , typename S >
std::unique_ptr< T > clanguml::util::unique_pointer_cast ( std::unique_ptr< S > &&  p)
noexcept

Definition at line 137 of file util.h.

138{
139 if (T *const converted = dynamic_cast<T *>(p.get())) {
140 std::move(p).release(); // NOLINT
141 return std::unique_ptr<T>{converted};
142 }
143
144 return {};
145}

Variable Documentation

◆ kDefaultMessageCommentWidth

constexpr unsigned clanguml::util::kDefaultMessageCommentWidth {25U}
constexpr

Definition at line 33 of file util.h.

◆ WHITESPACE

const auto clanguml::util::WHITESPACE = " \n\r\t\f\v"
static

Definition at line 29 of file util.cc.