7 #ifndef TREELITE_COMMON_H_ 8 #define TREELITE_COMMON_H_ 11 #include <dmlc/logging.h> 12 #include <dmlc/json.h> 13 #include <dmlc/data.h> 33 #define CLONEABLE_BOILERPLATE(className) \ 34 explicit className(const className& other) = default; \ 35 explicit className(className&& other) = default; \ 36 Cloneable* clone() const override { \ 37 return new className(*this); \ 39 Cloneable* move_clone() override { \ 40 return new className(std::move(*this)); \ 50 static_assert(std::is_base_of<Cloneable, T>::value,
51 "DeepCopyUniquePtr requires a Cloneable type");
55 : ptr(dynamic_cast<T*>(other.clone())) {}
58 : ptr(dynamic_cast<T*>(other.move_clone())) {}
60 : ptr(dynamic_cast<T*>(other.ptr->clone())) {}
62 : ptr(std::move(other.ptr)) {}
64 inline T& operator*() {
67 const inline T& operator*()
const {
71 return ptr.operator->();
73 const T* operator->()
const {
74 return ptr.operator->();
78 std::unique_ptr<T> ptr;
90 template<
typename T,
typename ...Args>
93 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
109 template <
typename T>
111 return std::move(*ptr.get());
124 inline void WrapText(std::ostringstream* p_stm,
size_t* p_length,
125 const std::string& str,
size_t textwidth) {
126 std::ostringstream& stm = *p_stm;
127 size_t& length = *p_length;
128 if (length + str.length() + 2 <= textwidth) {
130 length += str.length() + 2;
132 stm <<
"\n " << str <<
", ";
133 length = str.length() + 4;
146 template<
class Iter,
class T>
149 Iter i = std::lower_bound(begin, end, val);
150 if (i != end && !(val < *i)) {
162 template <
typename T>
164 std::ostringstream oss;
166 const std::streamsize ss = std::cout.precision();
167 oss << std::setprecision(std::numeric_limits<T>::digits10 + 2) << value
168 << std::setprecision(ss);
180 const std::vector<std::string>& lines) {
181 std::unique_ptr<dmlc::Stream> fo(dmlc::Stream::Create(filename.c_str(),
"w"));
182 dmlc::ostream os(fo.get());
183 std::copy(lines.begin(), lines.end(),
184 std::ostream_iterator<std::string>(os,
"\n"));
186 os.set_stream(
nullptr);
197 const std::vector<std::string>& lines,
198 std::function<std::string(std::string)> func) {
199 auto& dest = *p_dest;
200 std::transform(lines.begin(), lines.end(), std::back_inserter(dest), func);
209 template <
typename T>
211 static_assert(std::is_same<T, float>::value
212 || std::is_same<T, double>::value
213 || std::is_same<T, int>::value
214 || std::is_same<T, int8_t>::value
215 || std::is_same<T, uint32_t>::value,
216 "unsupported data type for TextToNumber; use float, double, " 217 "int, int8_t, or uint32_t.");
224 float val = std::strtof(str.c_str(), &endptr);
225 if (errno == ERANGE) {
226 LOG(FATAL) <<
"Range error while converting string to double";
228 else if (errno != 0) {
229 LOG(FATAL) <<
"Unknown error";
231 else if (*endptr !=
'\0') {
232 LOG(FATAL) <<
"String does not represent a valid floating-point number";
241 double val = std::strtod(str.c_str(), &endptr);
242 if (errno == ERANGE) {
243 LOG(FATAL) <<
"Range error while converting string to double";
245 else if (errno != 0) {
246 LOG(FATAL) <<
"Unknown error";
248 else if (*endptr !=
'\0') {
249 LOG(FATAL) <<
"String does not represent a valid floating-point number";
258 long int val = std::strtol(str.c_str(), &endptr, 10);
259 if (errno == ERANGE || val < INT_MIN || val > INT_MAX) {
260 LOG(FATAL) <<
"Range error while converting string to int";
262 else if (errno != 0) {
263 LOG(FATAL) <<
"Unknown error";
265 else if (*endptr !=
'\0') {
266 LOG(FATAL) <<
"String does not represent a valid integer";
268 return static_cast<int>(val);
275 long int val = std::strtol(str.c_str(), &endptr, 10);
276 if (errno == ERANGE || val < INT8_MIN || val > INT8_MAX) {
277 LOG(FATAL) <<
"Range error while converting string to int8_t";
279 else if (errno != 0) {
280 LOG(FATAL) <<
"Unknown error";
282 else if (*endptr !=
'\0') {
283 LOG(FATAL) <<
"String does not represent a valid integer";
285 return static_cast<int8_t
>(val);
290 static_assert(
sizeof(uint32_t) <=
sizeof(
unsigned long int),
291 "unsigned long int too small to hold uint32_t");
294 unsigned long int val = std::strtoul(str.c_str(), &endptr, 10);
295 if (errno == ERANGE || val > UINT32_MAX) {
296 LOG(FATAL) <<
"Range error while converting string to uint32_t";
298 else if (errno != 0) {
299 LOG(FATAL) <<
"Unknown error";
301 else if (*endptr !=
'\0') {
302 LOG(FATAL) <<
"String does not represent a valid integer";
304 return static_cast<uint32_t
>(val);
313 template <
typename T>
314 inline std::vector<T>
TextToArray(
const std::string& text,
int num_entry) {
315 std::vector<T> array;
316 std::istringstream ss(text);
318 for (
int i = 0; i < num_entry; ++i) {
319 std::getline(ss, token,
' ');
320 array.push_back(TextToNumber<T>(token));
331 inline std::vector<std::string>
Split(
const std::string& text,
char delim) {
332 std::vector<std::string> array;
333 std::istringstream ss(text);
335 while (std::getline(ss, token, delim)) {
336 array.push_back(token);
343 #endif // TREELITE_COMMON_H_
std::vector< T > TextToArray(const std::string &text, int num_entry)
convert text to number array
void WriteToFile(const std::string &filename, const std::vector< std::string > &lines)
write a sequence of strings to a text file, with newline character ( ) inserted between strings...
void TransformPushBack(std::vector< std::string > *p_dest, const std::vector< std::string > &lines, std::function< std::string(std::string)> func)
apply a given transformation to a sequence of strings and append them to another sequence.
std::string ToString(T value)
obtain a string representation of primitive type using ostringstream
abstract interface for classes that can be cloned
a wrapper around std::unique_ptr that supports deep copying and moving.
std::vector< std::string > Split(const std::string &text, char delim)
split text using a delimiter
Iter binary_search(Iter begin, Iter end, const T &val)
perform binary search on the range [begin, end).
defines configuration macros of treelite
void WrapText(std::ostringstream *p_stm, size_t *p_length, const std::string &str, size_t textwidth)
insert a string into a string stream, adding a newline character ( ) so that the string stream has no...
T && MoveUniquePtr(const std::unique_ptr< T > &ptr)
utility function to move an object pointed by a std::unique_ptr. After the move operation, the unique_ptr will hold an invalid object. Usage example:
std::unique_ptr< T > make_unique(Args &&...args)
construct a new object of type T and wraps it with a std::unique_ptr. This is support legacy compiles...
T TextToNumber(const std::string &str)
convert text to number