Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move non-templated function definitions out of header files in mrtrix.h and stats.h #2809

Merged
merged 5 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmd/labelstats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

#include "connectome/connectome.h"

#include <iomanip>

using namespace MR;
using namespace App;

Expand Down
2 changes: 2 additions & 0 deletions core/file/dicom/element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "debug.h"
#include "file/path.h"

#include <iomanip>

namespace MR {
namespace File {
namespace Dicom {
Expand Down
136 changes: 136 additions & 0 deletions core/mrtrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

#include "mrtrix.h"

#include <cstdarg>

namespace MR {

/************************************************************************
Expand Down Expand Up @@ -128,4 +130,138 @@ bool match(const std::string &pattern, const std::string &text, bool ignore_case
return __match(pattern.c_str(), text.c_str());
}

std::istream &getline(std::istream &stream, std::string &string) {
std::getline(stream, string);
if (!string.empty())
if (string[string.size() - 1] == 015)
string.resize(string.size() - 1);
return stream;
}

std::string &add_line(std::string &original, const std::string &new_line) {
return original.empty() ? (original = new_line) : (original += "\n" + new_line);
}

std::string shorten(const std::string &text, size_t longest, size_t prefix) {
if (text.size() > longest)
return (text.substr(0, prefix) + "..." + text.substr(text.size() - longest + prefix + 3));
else
return text;
Comment on lines +148 to +149

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use 'else' after 'return' [readability-else-after-return]

Suggested change
else
return text;
return text;

}

std::string lowercase(const std::string &string) {
std::string ret;
ret.resize(string.size());
transform(string.begin(), string.end(), ret.begin(), tolower);
return ret;
}

std::string uppercase(const std::string &string) {
std::string ret;
ret.resize(string.size());
transform(string.begin(), string.end(), ret.begin(), toupper);
return ret;
}

std::string printf(const char *format, ...) {
size_t len = 0;
va_list list1, list2;
va_start(list1, format);
va_copy(list2, list1);
len = vsnprintf(nullptr, 0, format, list1) + 1;
va_end(list1);
VLA(buf, char, len);
vsnprintf(buf, len, format, list2);
va_end(list2);
return buf;
}

std::string strip(const std::string &string, const std::string &ws, bool left, bool right) {
const std::string::size_type start = (left ? string.find_first_not_of(ws) : 0);
if (start == std::string::npos)
return "";
const std::string::size_type end = (right ? string.find_last_not_of(ws) + 1 : std::string::npos);
return string.substr(start, end - start);
}

std::string unquote(const std::string &string) {
if (string.size() <= 2)
return string;
if (!(string.front() == '\"' && string.back() == '\"'))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: boolean expression can be simplified by DeMorgan's theorem [readability-simplify-boolean-expr]

Suggested change
if (!(string.front() == '\"' && string.back() == '\"'))
if (string.front() != '\"' || string.back() != '\"')

return string;
std::string substring = string.substr(1, string.size() - 2);
if (std::none_of(substring.begin(), substring.end(), [](const char &c) { return c == '\"'; }))
return substring;
return string;
}

void replace(std::string &string, char orig, char final) {
for (auto &c : string)
if (c == orig)
c = final;
}

void replace(std::string &str, const std::string &from, const std::string &to) {
if (from.empty())
return;
size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length();
}
}

std::vector<std::string> split_lines(const std::string &string, bool ignore_empty_fields, size_t num) {
return split(string, "\n", ignore_empty_fields, num);
}

size_t char_is_dash(const char *arg) {
assert(arg != nullptr);
if (arg[0] == '-')
return 1;
if (arg[0] == '\0' || arg[1] == '\0' || arg[2] == '\0')
return 0;
const unsigned char *uarg = reinterpret_cast<const unsigned char *>(arg);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use reinterpret_cast [cppcoreguidelines-pro-type-reinterpret-cast]

  const unsigned char *uarg = reinterpret_cast<const unsigned char *>(arg);
                              ^

if (uarg[0] == 0xE2 && uarg[1] == 0x80 && (uarg[2] >= 0x90 && uarg[2] <= 0x95))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

  if (uarg[0] == 0xE2 && uarg[1] == 0x80 && (uarg[2] >= 0x90 && uarg[2] <= 0x95))
      ^

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

  if (uarg[0] == 0xE2 && uarg[1] == 0x80 && (uarg[2] >= 0x90 && uarg[2] <= 0x95))
                         ^

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

  if (uarg[0] == 0xE2 && uarg[1] == 0x80 && (uarg[2] >= 0x90 && uarg[2] <= 0x95))
                                             ^

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

  if (uarg[0] == 0xE2 && uarg[1] == 0x80 && (uarg[2] >= 0x90 && uarg[2] <= 0x95))
                                                                ^

return 3;
if (uarg[0] == 0xEF) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

  if (uarg[0] == 0xEF) {
      ^

if (uarg[1] == 0xB9 && (uarg[2] == 0x98 || uarg[2] == 0xA3))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

    if (uarg[1] == 0xB9 && (uarg[2] == 0x98 || uarg[2] == 0xA3))
        ^

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

    if (uarg[1] == 0xB9 && (uarg[2] == 0x98 || uarg[2] == 0xA3))
                            ^

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

    if (uarg[1] == 0xB9 && (uarg[2] == 0x98 || uarg[2] == 0xA3))
                                               ^

return 3;
if (uarg[1] == 0xBC && uarg[2] == 0x8D)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

    if (uarg[1] == 0xBC && uarg[2] == 0x8D)
        ^

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

    if (uarg[1] == 0xBC && uarg[2] == 0x8D)
                           ^

return 3;
}
return 0;
}

bool is_dash(const std::string &arg) {
const size_t nbytes = char_is_dash(arg.c_str());
return nbytes != 0 && nbytes == arg.size();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: implicit conversion bool -> 'size_t' (aka 'unsigned long') [readability-implicit-bool-conversion]

Suggested change
return nbytes != 0 && nbytes == arg.size();
return static_cast<size_t>(nbytes != 0 && nbytes == arg.size());

}

bool consume_dash(const char *&arg) {
size_t nbytes = char_is_dash(arg);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'nbytes' of type 'size_t' (aka 'unsigned long') can be declared 'const' [misc-const-correctness]

Suggested change
size_t nbytes = char_is_dash(arg);
size_t const nbytes = char_is_dash(arg);

arg += nbytes;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

  arg += nbytes;
      ^

return nbytes != 0;
}

std::string join(const std::vector<std::string> &V, const std::string &delimiter) {
std::string ret;
if (V.empty())
return ret;
ret = V[0];
for (std::vector<std::string>::const_iterator i = V.begin() + 1; i != V.end(); ++i)
ret += delimiter + *i;
return ret;
}

std::string join(const char *const *null_terminated_array, const std::string &delimiter) {
std::string ret;
if (!null_terminated_array)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: implicit conversion 'const char *const *' -> bool [readability-implicit-bool-conversion]

Suggested change
if (!null_terminated_array)
if (null_terminated_array == nullptr)

return ret;
ret = null_terminated_array[0];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

  ret = null_terminated_array[0];
        ^

for (const char *const *p = null_terminated_array + 1; *p; ++p)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

  for (const char *const *p = null_terminated_array + 1; *p; ++p)
                                                    ^

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: implicit conversion 'const char *' -> bool [readability-implicit-bool-conversion]

Suggested change
for (const char *const *p = null_terminated_array + 1; *p; ++p)
for (const char *const *p = null_terminated_array + 1; *p != nullptr; ++p)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]

  for (const char *const *p = null_terminated_array + 1; *p; ++p)
                                                             ^

ret += delimiter + *p;
return ret;
}

} // namespace MR
147 changes: 19 additions & 128 deletions core/mrtrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,10 @@
#ifndef __mrtrix_h__
#define __mrtrix_h__

#include <algorithm>
#include <array>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <climits>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <limits>
#include <sstream>
Expand All @@ -41,13 +34,7 @@ namespace MR {
//! read a line from the stream
/*! a replacement for the standard getline() function that also discards
* carriage returns if found at the end of the line. */
inline std::istream &getline(std::istream &stream, std::string &string) {
std::getline(stream, string);
if (string.size() > 0)
if (string[string.size() - 1] == 015)
string.resize(string.size() - 1);
return stream;
}
std::istream &getline(std::istream &stream, std::string &string);

template <typename X, typename ReturnType = int> struct max_digits {
static constexpr int value() { return 0; }
Expand All @@ -71,94 +58,37 @@ struct max_digits<X,
};

//! add a line to a string, taking care of inserting a newline if needed
inline std::string &add_line(std::string &original, const std::string &new_line) {
return original.size() ? (original += "\n" + new_line) : (original = new_line);
}
std::string &add_line(std::string &original, const std::string &new_line);

//! convert a long string to 'beginningofstring...endofstring' for display
inline std::string shorten(const std::string &text, size_t longest = 40, size_t prefix = 10) {
if (text.size() > longest)
return (text.substr(0, prefix) + "..." + text.substr(text.size() - longest + prefix + 3));
else
return text;
}
std::string shorten(const std::string &text, size_t longest = 40, size_t prefix = 10);

//! return lowercase version of string
inline std::string lowercase(const std::string &string) {
std::string ret;
ret.resize(string.size());
transform(string.begin(), string.end(), ret.begin(), tolower);
return ret;
}
std::string lowercase(const std::string &string);

//! return uppercase version of string
inline std::string uppercase(const std::string &string) {
std::string ret;
ret.resize(string.size());
transform(string.begin(), string.end(), ret.begin(), toupper);
return ret;
}
std::string uppercase(const std::string &string);

inline std::string printf(const char *format, ...) {
size_t len = 0;
va_list list1, list2;
va_start(list1, format);
va_copy(list2, list1);
len = vsnprintf(nullptr, 0, format, list1) + 1;
va_end(list1);
VLA(buf, char, len);
vsnprintf(buf, len, format, list2);
va_end(list2);
return buf;
}
std::string printf(const char *format, ...);

inline std::string
strip(const std::string &string, const std::string &ws = {" \0\t\r\n", 5}, bool left = true, bool right = true) {
std::string::size_type start = (left ? string.find_first_not_of(ws) : 0);
if (start == std::string::npos)
return "";
std::string::size_type end = (right ? string.find_last_not_of(ws) + 1 : std::string::npos);
return string.substr(start, end - start);
}
std::string
strip(const std::string &string, const std::string &ws = {" \0\t\r\n", 5}, bool left = true, bool right = true);

//! Remove quotation marks only if surrounding entire string
inline std::string unquote(const std::string &string) {
if (string.size() <= 2)
return string;
if (!(string.front() == '\"' && string.back() == '\"'))
return string;
const std::string substring = string.substr(1, string.size() - 2);
if (std::none_of(substring.begin(), substring.end(), [](const char &c) { return c == '\"'; }))
return substring;
return string;
}
std::string unquote(const std::string &string);

inline void replace(std::string &string, char orig, char final) {
for (auto &c : string)
if (c == orig)
c = final;
}
void replace(std::string &string, char orig, char final);

inline void replace(std::string &str, const std::string &from, const std::string &to) {
if (from.empty())
return;
size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length();
}
}
void replace(std::string &str, const std::string &from, const std::string &to);

std::vector<std::string> split(const std::string &string,
const char *delimiters = " \t\n",
bool ignore_empty_fields = false,
size_t num = std::numeric_limits<size_t>::max());

inline std::vector<std::string> split_lines(const std::string &string,
bool ignore_empty_fields = true,
size_t num = std::numeric_limits<size_t>::max()) {
return split(string, "\n", ignore_empty_fields, num);
}
std::vector<std::string> split_lines(const std::string &string,
bool ignore_empty_fields = true,
size_t num = std::numeric_limits<size_t>::max());

/*
inline int round (default_type x)
Expand All @@ -172,39 +102,16 @@ bool match(const std::string &pattern, const std::string &text, bool ignore_case
//! match a dash or any Unicode character that looks like one
/*! \note This returns the number of bytes taken up by the matched UTF8
* character, zero if no match. */
inline size_t char_is_dash(const char *arg) {
assert(arg != nullptr);
if (arg[0] == '-')
return 1;
if (arg[0] == '\0' || arg[1] == '\0' || arg[2] == '\0')
return 0;
const unsigned char *uarg = reinterpret_cast<const unsigned char *>(arg);
if (uarg[0] == 0xE2 && uarg[1] == 0x80 && (uarg[2] >= 0x90 && uarg[2] <= 0x95))
return 3;
if (uarg[0] == 0xEF) {
if (uarg[1] == 0xB9 && (uarg[2] == 0x98 || uarg[2] == 0xA3))
return 3;
if (uarg[1] == 0xBC && uarg[2] == 0x8D)
return 3;
}
return 0;
}
size_t char_is_dash(const char *arg);

//! match whole string to a dash or any Unicode character that looks like one
inline size_t is_dash(const std::string &arg) {
size_t nbytes = char_is_dash(arg.c_str());
return nbytes != 0 && nbytes == arg.size();
}
bool is_dash(const std::string &arg);

//! match current character to a dash or any Unicode character that looks like one
/*! \note If a match is found, this also advances the \a arg pointer to the next
* character in the string, which could be one or several bytes along depending on
* the width of the UTF8 character identified. */
inline bool consume_dash(const char *&arg) {
size_t nbytes = char_is_dash(arg);
arg += nbytes;
return nbytes != 0;
}
bool consume_dash(const char *&arg);

template <class T> inline std::string str(const T &value, int precision = 0) {
std::ostringstream stream;
Expand Down Expand Up @@ -451,15 +358,7 @@ Eigen::Matrix<ValueType, Eigen::Dynamic, Eigen::Dynamic> parse_matrix(const std:
return M;
}

inline std::string join(const std::vector<std::string> &V, const std::string &delimiter) {
std::string ret;
if (V.empty())
return ret;
ret = V[0];
for (std::vector<std::string>::const_iterator i = V.begin() + 1; i != V.end(); ++i)
ret += delimiter + *i;
return ret;
}
std::string join(const std::vector<std::string> &V, const std::string &delimiter);

template <typename T> inline std::string join(const std::vector<T> &V, const std::string &delimiter) {
std::string ret;
Expand All @@ -471,15 +370,7 @@ template <typename T> inline std::string join(const std::vector<T> &V, const std
return ret;
}

inline std::string join(const char *const *null_terminated_array, const std::string &delimiter) {
std::string ret;
if (!null_terminated_array)
return ret;
ret = null_terminated_array[0];
for (const char *const *p = null_terminated_array + 1; *p; ++p)
ret += delimiter + *p;
return ret;
}
std::string join(const char *const *null_terminated_array, const std::string &delimiter);

} // namespace MR

Expand Down
Loading
Loading