Skip to content
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
20 changes: 9 additions & 11 deletions src/stan/io/json/json_data_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <stan/io/json/json_handler.hpp>
#include <stan/io/json/rapidjson_parser.hpp>
#include <stan/io/var_context.hpp>
#include <stan/io/string_utils.hpp>
#include <algorithm>
#include <iostream>
#include <locale>
#include <ostream>
Expand All @@ -15,7 +17,6 @@
#include <string>
#include <utility>
#include <vector>
#include <boost/algorithm/string.hpp>

namespace stan {

Expand Down Expand Up @@ -145,9 +146,7 @@ class json_data_handler : public stan::json::json_handler {
array_start_r = 0;
}

inline std::string key_str() {
return boost::algorithm::join(key_stack, ".");
}
inline std::string key_str() { return stan::io::join(key_stack, "."); }

std::string outer_key_str() {
std::string result;
Expand Down Expand Up @@ -185,7 +184,7 @@ class json_data_handler : public stan::json::json_handler {
std::string key;
stack.pop_back();
while (!stack.empty()) {
key = boost::algorithm::join(stack, ".");
key = stan::io::join(stack, ".");
if (slot_types_map[key] == meta_type::ARRAY_OF_TUPLES)
return true;
stack.pop_back();
Expand All @@ -198,12 +197,12 @@ class json_data_handler : public stan::json::json_handler {
std::string key;
stack.pop_back();
while (!stack.empty()) {
key = boost::algorithm::join(stack, ".");
key = stan::io::join(stack, ".");
if (slot_dims_map.count(key) == 1)
return slot_dims_map[key];
stack.pop_back();
}
key = boost::algorithm::join(keys, ".");
key = stan::io::join(keys, ".");
if (slot_dims_map.count(key) != 1)
unexpected_error(key, "not an array");
return slot_dims_map[key];
Expand All @@ -214,13 +213,13 @@ class json_data_handler : public stan::json::json_handler {
std::string key;
stack.pop_back();
while (!stack.empty()) {
key = boost::algorithm::join(stack, ".");
key = stan::io::join(stack, ".");
if (slot_dims_map.count(key) == 1)
break;
stack.pop_back();
}
if (stack.empty()) {
key = boost::algorithm::join(key_stack, ".");
key = stan::io::join(key_stack, ".");
unexpected_error(key, "ill-formed array");
}
slot_dims_map[key] = update;
Expand Down Expand Up @@ -358,8 +357,7 @@ class json_data_handler : public stan::json::json_handler {
continue;
}
std::vector<size_t> all_dims;
std::vector<std::string> slots;
split(slots, var.first, boost::is_any_of("."), boost::token_compress_on);
std::vector<std::string> slots = stan::io::split(var.first, ".", true);
std::string slot;
for (size_t i = 0; i < slots.size(); ++i) {
slot.append(slots[i]);
Expand Down
27 changes: 13 additions & 14 deletions src/stan/io/stan_csv_reader.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef STAN_IO_STAN_CSV_READER_HPP
#define STAN_IO_STAN_CSV_READER_HPP

#include <boost/algorithm/string.hpp>
#include <stan/io/string_utils.hpp>
#include <stan/math/prim.hpp>
#include <cctype>
#include <istream>
Expand All @@ -15,8 +15,7 @@ namespace io {

inline void prettify_stan_csv_name(std::string& variable) {
if (variable.find_first_of(":.") != std::string::npos) {
std::vector<std::string> parts;
boost::split(parts, variable, boost::is_any_of(":"));
std::vector<std::string> parts = stan::io::split(variable, ":");
for (auto& part : parts) {
int pos = part.find('.');
if (pos > 0) {
Expand All @@ -25,7 +24,7 @@ inline void prettify_stan_csv_name(std::string& variable) {
part += "]";
}
}
variable = boost::algorithm::join(parts, ".");
variable = stan::io::join(parts, ".");
}
}

Expand Down Expand Up @@ -126,10 +125,10 @@ class stan_csv_reader {
size_t equal = lhs.find("=");
if (equal != std::string::npos) {
name = lhs.substr(0, equal);
boost::trim(name);
stan::io::trim(name);
value = lhs.substr(equal + 1, lhs.size());
boost::trim(value);
boost::replace_first(value, " (Default)", "");
stan::io::trim(value);
stan::io::remove_first(value, " (Default)");
} else {
if (lhs.compare(" data") == 0) {
ss >> comment;
Expand All @@ -138,9 +137,9 @@ class stan_csv_reader {
size_t equal = lhs.find("=");
if (equal != std::string::npos) {
name = lhs.substr(0, equal);
boost::trim(name);
stan::io::trim(name);
value = lhs.substr(equal + 2, lhs.size());
boost::replace_first(value, " (Default)", "");
stan::io::remove_first(value, " (Default)");
}

if (name.compare("file") == 0)
Expand Down Expand Up @@ -176,7 +175,7 @@ class stan_csv_reader {
std::stringstream(value) >> metadata.chain_id;
} else if (name.compare("init") == 0) {
metadata.init = value;
boost::trim(metadata.init);
stan::io::trim(metadata.init);
} else if (name.compare("seed") == 0) {
std::stringstream(value) >> metadata.seed;
metadata.random_seed = false;
Expand Down Expand Up @@ -209,7 +208,7 @@ class stan_csv_reader {
while (ss.good()) {
std::string token;
std::getline(ss, token, ',');
boost::trim(token);
stan::io::trim(token);

if (prettify_name) {
prettify_stan_csv_name(token);
Expand Down Expand Up @@ -239,7 +238,7 @@ class stan_csv_reader {

// parse stepsize
std::getline(ss, line, '='); // stepsize
boost::trim(line);
stan::io::trim(line);
ss >> adaptation.step_size;
if (lines == 2) // ADVI reports stepsize, no metric
return;
Expand All @@ -265,7 +264,7 @@ class stan_csv_reader {
for (int col = 0; col < cols; col++) {
std::string token;
std::getline(line_ss, token, ',');
boost::trim(token);
stan::io::trim(token);
std::stringstream(token) >> adaptation.metric(row, col);
}
std::getline(ss, line);
Expand Down Expand Up @@ -335,7 +334,7 @@ class stan_csv_reader {
std::stringstream ls(line);
for (int col = 0; col < cols; col++) {
std::getline(ls, line, ',');
boost::trim(line);
stan::io::trim(line);
try {
samples(row, col) = static_cast<double>(std::stold(line));
// If the value read is out of the range of representable values by
Expand Down
108 changes: 108 additions & 0 deletions src/stan/io/string_utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#ifndef STAN_IO_STRING_UTILS_HPP
#define STAN_IO_STRING_UTILS_HPP

#include <string>
#include <string_view>
#include <vector>

namespace stan {
namespace io {

/**
* Joins a vector of strings/string_views into a single string,
* separated by `delimiter`.
*
* @param container strings to join
* @param delimiter separator inserted between parts
* @return the joined string
*/
template <typename T>
inline std::string join(T&& container, const std::string_view& delimiter) {
if (container.empty()) {
return "";
}
std::size_t total = (container.size() - 1) * delimiter.size();
for (const auto& element : container) {
total += std::string_view(element).size();
}
std::string result;
result.reserve(total);
bool first = true;
for (const auto& element : container) {
if (!first) {
result.append(delimiter);
}
result.append(std::string_view(element));
first = false;
}
return result;
}

/**
* Splits a string on any character found in `delimiters`.
*
* Empty substrings are preserved. Empty delimiters return the input as a
* single element. When `compress_delims` is true, consecutive delimiters are
* treated as a single delimiter.
*
* @param input string to split
* @param delimiters separators between parts
* @param compress_tokens whether to combine consecutive delimiters
* @return the split strings
*/
inline std::vector<std::string> split(const std::string_view& input,
const std::string_view& delimiters,
bool compress_delims = false) {
std::vector<std::string> result;
std::size_t start = 0;
while (start <= input.size()) {
const std::size_t end = input.find_first_of(delimiters, start);
if (end == std::string_view::npos) {
result.emplace_back(input.substr(start));
break;
}
result.emplace_back(input.substr(start, end - start));
start = end + 1;
if (compress_delims) {
const std::size_t next = input.find_first_not_of(delimiters, start);
start = (next == std::string_view::npos) ? input.size() : next;
}
}
return result;
}

/**
* Remove leading and trailing whitespace from a string in place.
*
* @param input string to trim
*/
inline void trim(std::string& input) {
constexpr std::string_view whitespace = " \t\n\r\f\v";
const std::size_t start = input.find_first_not_of(whitespace);
if (start == std::string::npos) {
input.clear();
return;
}
const std::size_t end = input.find_last_not_of(whitespace);
input.erase(end + 1);
input.erase(0, start);
}

/**
* Removes the first occurrence of a substring from a string in place.
*
* @param input string to modify
* @param substring substring to remove
*/
inline void remove_first(std::string& input,
const std::string_view& substring) {
const std::size_t position = input.find(substring);
if (position != std::string::npos) {
input.erase(position, substring.size());
}
}

} // namespace io
} // namespace stan

#endif
1 change: 0 additions & 1 deletion src/test/unit/io/stan_csv_reader_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include <stan/io/stan_csv_reader.hpp>
#include <test/unit/util.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <gtest/gtest.h>
#include <fstream>
#include <sstream>
Expand Down
22 changes: 9 additions & 13 deletions src/test/unit/services/check_adaptation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <stdio.h>
#include <string>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <stan/io/string_utils.hpp>

namespace stan {
namespace test {
Expand All @@ -28,9 +28,8 @@ void check_adaptation(const size_t& num_params,
break;
}
}
std::vector<std::string> strs;
boost::split(strs, param_strings[offset], boost::is_any_of(", "),
boost::token_compress_on);
std::vector<std::string> strs
= stan::io::split(param_strings[offset], ", ", true);
EXPECT_EQ(num_params, strs.size());
for (size_t i = 0; i < num_params; i++) {
ASSERT_NEAR(param_vals[i], test::unit::stod(strs[i]), err_margin);
Expand All @@ -51,9 +50,8 @@ void check_adaptation(const size_t& num_rows, const size_t& num_cols,
}
}
for (size_t i = 0, ij = 0; i < num_rows; i++) {
std::vector<std::string> strs;
boost::split(strs, param_strings[offset + i], boost::is_any_of(", "),
boost::token_compress_on);
std::vector<std::string> strs
= stan::io::split(param_strings[offset + i], ", ", true);
EXPECT_EQ(num_cols, strs.size());
for (size_t j = 0; j < num_cols; j++, ij++) {
ASSERT_NEAR(param_vals[ij], test::unit::stod(strs[j]), err_margin);
Expand All @@ -74,9 +72,8 @@ void check_different(const size_t& num_params,
break;
}
}
std::vector<std::string> strs;
boost::split(strs, param_strings[offset], boost::is_any_of(", "),
boost::token_compress_on);
std::vector<std::string> strs
= stan::io::split(param_strings[offset], ", ", true);
EXPECT_EQ(num_params, strs.size());
for (size_t i = 0; i < num_params; i++) {
ASSERT_GT(fabs(param_vals[i] - test::unit::stod(strs[i])), margin);
Expand All @@ -97,9 +94,8 @@ void check_different(const size_t& num_rows, const size_t& num_cols,
}
}
for (size_t i = 0, ij = 0; i < num_rows; i++) {
std::vector<std::string> strs;
boost::split(strs, param_strings[offset + i], boost::is_any_of(", "),
boost::token_compress_on);
std::vector<std::string> strs
= stan::io::split(param_strings[offset + i], ", ", true);
EXPECT_EQ(num_cols, strs.size());
for (size_t j = 0; j < num_cols; j++, ij++) {
ASSERT_GT(fabs(param_vals[ij] - test::unit::stod(strs[j])), margin);
Expand Down
1 change: 0 additions & 1 deletion src/test/unit/services/optimize/laplace_jacobian_test.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#include <boost/algorithm/string.hpp>
#include <gtest/gtest.h>
#include <stan/callbacks/stream_logger.hpp>
#include <stan/callbacks/stream_writer.hpp>
Expand Down
1 change: 0 additions & 1 deletion src/test/unit/services/optimize/laplace_sample_test.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#include <boost/algorithm/string.hpp>
#include <gtest/gtest.h>
#include <stan/callbacks/stream_logger.hpp>
#include <stan/callbacks/stream_writer.hpp>
Expand Down
Loading
Loading