File: Util2.h

package info (click to toggle)
pymol 3.1.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 74,084 kB
  • sloc: cpp: 482,660; python: 89,328; ansic: 29,512; javascript: 6,792; sh: 84; makefile: 25
file content (172 lines) | stat: -rw-r--r-- 4,025 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*
 * Utility functions
 *
 * (c) 2015 Schrodinger, Inc.
 */

#pragma once

#include <algorithm>
#include <array>
#include <string>
#include <vector>

#include <string.h>
#include <sstream>

#include "pymol/type_traits.h"
#include "pymol/zstring_view.h"

std::vector<std::string> strsplit(const std::string &s, char delim=0);

bool cstrlessnat(const char * a, const char * b);
bool strlessnat(const std::string& a, const std::string& b);

/**
 * C string comparison class
 */
struct cstrless_t {
  bool operator()(const char * a, const char * b) const {
    return strcmp(a, b) < 0;
  }
};

bool p_strstartswith(const char * s, const char * prefix);
bool p_strcasestartswith(const char * s, const char * prefix);

namespace pymol
{
namespace join_to_string_detail
{
inline void join_to_string_impl(std::ostringstream&){};

template <typename T, typename... OtherTs>
void join_to_string_impl(std::ostringstream& stream, T&& t, OtherTs&&... ts)
{
  stream << std::forward<T>(t);
  join_to_string_impl(stream, std::forward<OtherTs>(ts)...);
}
} // namespace join_to_string_detail

/**
 * Joins data into std::string.
 * @param ts printable types to be joined into a string
 * @return joined string
 * Note: Types must be supported be std::ostringstream::operator<<
 */

template <typename... PrintableTs>
std::string join_to_string(PrintableTs&&... ts)
{
  std::ostringstream stream;
  join_to_string_detail::join_to_string_impl(
      stream, std::forward<PrintableTs>(ts)...);
  return stream.str();
}

namespace string_format_detail
{
template <typename T> const T& fwdArgs(const T& t)
{
#if defined(__clang__) || !defined(__GNUC__) || __GNUC__ >= 5
  // Not available in GCC 4.8
  static_assert(std::is_trivially_copyable<T>::value, "");
#endif
  return t;
}

inline const char* fwdArgs(const std::string& t)
{
  return t.c_str();
}

inline const char* fwdArgs(const pymol::zstring_view& t)
{
  return t.c_str();
}

template <typename... FmtArgs>
std::string string_format_impl(const char* const fmt, FmtArgs&&... fmtargs)
{
  auto size = snprintf(nullptr, 0, fmt, fmtargs...);
  std::string tmp(size, ' ');
  snprintf(&tmp[0], size + 1, fmt, fmtargs...);
  return tmp;
}

} // namespace string_format_detail

/**
 * C++ version of sprintf
 * @param fmt formatting string
 * @param fmtargs formatting string arguments
 * @return result as std::string
 *
 * Note: For std::string arguments, the underlying null-terminated string will
 * be used.
 */

template <std::size_t N, typename... FmtArgs>
std::string string_format(const char (&fmt)[N], FmtArgs&&... fmtargs)
{
  static_assert(N > 1, "Format string must not be empty");
  return string_format_detail::string_format_impl(
      fmt, string_format_detail::fwdArgs(std::forward<FmtArgs>(fmtargs))...);
}

/**
 * C++20's std::string::start_with
 * @param str string whose contents will be checked
 * @param pre candidate prefix string
 * @return true if str begins with pre
 *
 */
inline bool starts_with(pymol::zstring_view str, pymol::zstring_view pre)
{
  return str.starts_with(pre);
}

double pretty_f2d(float v);

/**
 * Compares two strings with consideration of case sensitivity
 * @param str1 first string
 * @param str2 second string
 * @param case_insensitive determines whether the comparison should not consider
 * case
 */

bool string_equal_case(pymol::zstring_view str1, pymol::zstring_view str2,
    bool case_insensitive = true);

template <typename T> struct cache_value {
  using value_type = T;

  value_type value = value_type{};

  cache_value() = default;

  cache_value(T t)
      : value(std::move(t))
  {
  }

  cache_value(const cache_value&) {}
  cache_value& operator=(const cache_value&) { return *this; }
  cache_value(cache_value&& other)
  {
    std::swap(value, other.value);
  }
  cache_value& operator=(cache_value&& other)
  {
    std::swap(value, other.value);
    return *this;
  }

  operator T&() { return value; }
};

template <typename T, std::size_t N>
using cache_array = std::array<cache_value<T>, N>;

} // namespace pymol