Skip to content

Commit a98ef5a

Browse files
committed
fable: Remove Boost dependency
BREAKING CHANGE: Packages that relied on fable to provide Boost as a transitive dependency need to add it to their project themselves: For example, with CMake: ```cmake find_package(Boost COMPONENTS headers filesystem REQUIRED) target_link_libraries(${yourTarget} PUBLIC Boost::headers Boost::filesystem) ``` And with Conan: ```python \# class ConanFile: def requirements(self): self.requires("boost/1.78") ```
1 parent 5fcc653 commit a98ef5a

File tree

11 files changed

+46
-58
lines changed

11 files changed

+46
-58
lines changed

fable/CMakeLists.txt

+1-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ set(FABLE_VERSION_U32 0 CACHE STRING "Fable version as (MAJOR<<16)|(MINOR<<8)|PA
1010
include(GNUInstallDirs)
1111

1212
# Library ------------------------------------------------------------
13-
find_package(Boost COMPONENTS headers filesystem REQUIRED)
1413
find_package(fmt REQUIRED)
1514
find_package(nlohmann_json REQUIRED)
1615

@@ -51,8 +50,6 @@ target_include_directories(fable
5150
)
5251
target_link_libraries(fable
5352
PUBLIC
54-
Boost::headers
55-
Boost::filesystem
5653
fmt::fmt
5754
nlohmann_json::nlohmann_json
5855
)
@@ -68,6 +65,7 @@ endif()
6865
include(CTest)
6966
if(BUILD_TESTING)
7067
find_package(GTest REQUIRED)
68+
find_package(Boost COMPONENTS headers filesystem REQUIRED)
7169
include(GoogleTest)
7270

7371
add_executable(test-fable

fable/conanfile.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ def set_version(self):
4646
self.version = git.run("describe --dirty=-dirty")[1:]
4747

4848
def requirements(self):
49-
self.requires("boost/[>=1.65.1]")
5049
self.requires("fmt/9.1.0")
5150
self.requires("nlohmann_json/3.11.2")
5251

5352
def build_requirements(self):
5453
self.test_requires("gtest/1.13.0")
54+
self.test_requires("boost/[>=1.65.1]")
5555

5656
def layout(self):
5757
cmake.cmake_layout(self)
@@ -88,9 +88,6 @@ def package(self):
8888
if self.should_install:
8989
cm.install()
9090

91-
def package_id(self):
92-
self.info.requires["boost"].full_package_mode()
93-
9491
def package_info(self):
9592
self.cpp_info.set_property("cmake_find_mode", "both")
9693
self.cpp_info.set_property("cmake_file_name", "fable")

fable/include/fable/conf.hpp

+2-8
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,12 @@
5353
#include <functional> // for function<>
5454
#include <string> // for string
5555
#include <vector> // for vector<>
56+
#include <filesystem> // for path
5657

5758
#include <fmt/format.h> // for fmt::format
5859

5960
#include <fable/json.hpp> // for Json
6061

61-
// Forward declaration:
62-
namespace boost {
63-
namespace filesystem {
64-
class path;
65-
} // namespace filesystem
66-
} // namespace boost
67-
6862
namespace fable {
6963

7064
class ConfError;
@@ -323,7 +317,7 @@ class Conf {
323317
* - If the path is relative and file is not stdin, return relative to
324318
* the file.
325319
*/
326-
boost::filesystem::path resolve_file(const boost::filesystem::path& filename) const;
320+
std::filesystem::path resolve_file(const std::filesystem::path& filename) const;
327321
std::string resolve_file(const std::string& filename) const;
328322

329323
template <typename... Args>

fable/include/fable/environment.hpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@
2727
#include <map> // for map<>
2828
#include <string> // for string
2929
#include <utility> // for pair<>, move, make_pair
30-
31-
#include <boost/optional.hpp> // for optional<>
30+
#include <optional> // for optional<>
3231

3332
namespace fable {
3433

@@ -63,10 +62,10 @@ class Environment {
6362
*
6463
* This is roughly equivalent to ${KEY}.
6564
*/
66-
boost::optional<std::string> get(const std::string& key) const {
65+
std::optional<std::string> get(const std::string& key) const {
6766
return get(key, prefer_external_);
6867
}
69-
boost::optional<std::string> get(const std::string& key, bool prefer_external) const;
68+
std::optional<std::string> get(const std::string& key, bool prefer_external) const;
7069

7170
/**
7271
* Return the value of a literal key, trying both environment and internal

fable/include/fable/schema.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ class Schema : public schema::Interface {
253253
const std::string& description() const override { return impl_->description(); }
254254
void set_description(const std::string& s) override { return impl_->set_description(s); }
255255
Json usage() const override { return impl_->usage(); }
256-
Json json_schema() const override { return impl_->json_schema(); };
256+
Json json_schema() const override { return impl_->json_schema(); }
257257
void validate(const Conf& c) const override { impl_->validate(c); }
258258
void to_json(Json& j) const override { impl_->to_json(j); }
259259
void from_conf(const Conf& c) override { impl_->from_conf(c); }

fable/include/fable/schema/map.hpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@
3030
#include <string> // for string
3131
#include <utility> // for move
3232
#include <vector> // for vector<>
33-
34-
#include <boost/optional.hpp> // for optional<>
33+
#include <optional> // for optional<>
3534

3635
#include <fable/schema/interface.hpp> // for Base<>
3736

@@ -126,7 +125,7 @@ class Map : public Base<Map<T, P>> {
126125
c.assert_has(k);
127126
}
128127

129-
boost::optional<std::regex> pattern;
128+
std::optional<std::regex> pattern;
130129
if (!pattern_.empty()) {
131130
*pattern = std::regex(pattern_);
132131
}

fable/include/fable/utility.hpp

+4-13
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,12 @@
2323
#pragma once
2424

2525
#include <string> // for string
26+
#include <ostream> // for ostream
2627

27-
#include <fable/conf.hpp> // for Conf
28-
#include <fable/json.hpp> // for Json
28+
#include <fable/fable_fwd.hpp>
2929

3030
namespace fable {
3131

32-
// Forward declarations:
33-
class ConfError; // from <fable/error.hpp>
34-
class SchemaError; // from <fable/error.hpp>
35-
class Environment; // from <fable/environment.hpp>
36-
3732
/**
3833
* Read a file and parse the contents to JSON.
3934
*
@@ -44,9 +39,7 @@ Json read_json_from_file(const char* filepath);
4439

4540
Json read_json_from_stdin();
4641

47-
inline Json read_json_from_file(const std::string& filepath) {
48-
return read_json_from_file(filepath.c_str());
49-
}
42+
Json read_json_from_file(const std::string& filepath);
5043

5144
Json read_json(const std::string& filepath_or_stdin);
5245

@@ -57,9 +50,7 @@ Conf read_conf_from_file(const char* filepath);
5750

5851
Conf read_conf_from_stdin();
5952

60-
inline Conf read_conf_from_file(const std::string& filepath) {
61-
return read_conf_from_file(filepath.c_str());
62-
}
53+
Conf read_conf_from_file(const std::string& filepath);
6354

6455
Conf read_conf(const std::string& filepath_or_stdin);
6556

fable/src/fable/conf.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222

2323
#include <fable/conf.hpp>
2424

25-
#include <fstream> // for ifstream
26-
#include <string> // for string
27-
#include <vector> // for vector<>
25+
#include <filesystem> // for path
26+
#include <fstream> // for ifstream
27+
#include <string> // for string
28+
#include <vector> // for vector<>
2829

29-
#include <fmt/format.h> // for fmt::format
30-
#include <boost/filesystem.hpp> // for path
30+
#include <fmt/format.h> // for fmt::format
3131

3232
#include <fable/error.hpp> // for ConfError, WrongType, MissingProperty
3333
#include <fable/json.hpp> // for NLOHMANN_JSON_ALLOW_COMMENTS
@@ -148,8 +148,8 @@ void Conf::assert_has_type(const JsonPointer& key, JsonType t) const {
148148
}
149149
}
150150

151-
boost::filesystem::path Conf::resolve_file(const boost::filesystem::path& filepath) const {
152-
namespace fs = boost::filesystem;
151+
std::filesystem::path Conf::resolve_file(const std::filesystem::path& filepath) const {
152+
namespace fs = std::filesystem;
153153

154154
auto fp = filepath;
155155
if (fp.is_relative()) {
@@ -164,7 +164,7 @@ boost::filesystem::path Conf::resolve_file(const boost::filesystem::path& filepa
164164
}
165165

166166
std::string Conf::resolve_file(const std::string& filepath) const {
167-
return resolve_file(boost::filesystem::path(filepath)).native();
167+
return resolve_file(std::filesystem::path(filepath)).native();
168168
}
169169

170170
[[noreturn]] void Conf::throw_error(const std::string& msg) const { throw ConfError{*this, msg}; }

fable/src/fable/environment.cpp

+5-6
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@
2323

2424
#include <fable/environment.hpp>
2525

26-
#include <cstdlib> // for getenv
27-
#include <string> // for string
28-
29-
#include <boost/optional.hpp> // for optional<>
26+
#include <cstdlib> // for getenv
27+
#include <stdexcept> // for out_of_range
28+
#include <string> // for string
3029

3130
namespace fable {
3231

@@ -40,8 +39,8 @@ std::string slice(const std::string& s, size_t start) { return s.substr(start);
4039

4140
} // anonymous namespace
4241

43-
boost::optional<std::string> Environment::get(const std::string& key, bool prefer_external) const {
44-
boost::optional<std::string> value;
42+
std::optional<std::string> Environment::get(const std::string& key, bool prefer_external) const {
43+
std::optional<std::string> value;
4544

4645
auto try_external = [&]() -> bool {
4746
char* s = std::getenv(key.c_str());

fable/src/fable/environment_test.cpp

+4-5
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,19 @@
2222

2323
#include <cstdlib> // for getenv
2424
#include <string> // for string
25+
#include <optional> // for optional<>
2526

2627
#include <gtest/gtest.h> // for TEST, ASSERT_EQ, ...
27-
#include <boost/optional.hpp> // for optional<>
28-
#include <boost/optional/optional_io.hpp>
2928

3029
#include <fable/environment.hpp> // for Environment
3130

3231
#define ENV_VAR_HOME "HOME"
3332
#define ENV_VAR_NONEXISTENT "NONEXISTENT_ENTRY"
3433

35-
boost::optional<std::string> getenv_optional(const std::string& key) {
34+
std::optional<std::string> getenv_optional(const std::string& key) {
3635
char* v = getenv(key.c_str());
3736
if (v == nullptr) {
38-
return boost::none;
37+
return std::nullopt;
3938
} else {
4039
return std::string(v);
4140
}
@@ -47,7 +46,7 @@ TEST(fable_environment, get_variable) {
4746
ASSERT_EQ(env.get(ENV_VAR_HOME), getenv_optional(ENV_VAR_HOME));
4847
if (!getenv_optional(ENV_VAR_NONEXISTENT)) {
4948
ASSERT_THROW(env.require(ENV_VAR_NONEXISTENT), std::out_of_range);
50-
ASSERT_EQ(env.get(ENV_VAR_NONEXISTENT), boost::none);
49+
ASSERT_EQ(env.get(ENV_VAR_NONEXISTENT), std::nullopt);
5150
}
5251
}
5352

fable/src/fable/utility.cpp

+15-3
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@
2222

2323
#include <fable/utility.hpp>
2424

25-
#include <boost/algorithm/string.hpp> // for replace_all
26-
25+
#include <algorithm> // for replace
2726
#include <fstream> // for ifstream
2827
#include <iostream> // for cin, ostream
2928
#include <iterator> // for istreambuf_iterator
@@ -43,6 +42,10 @@ Json read_json_from_file(const char* filepath) {
4342
return parse_json(ifs);
4443
}
4544

45+
Json read_json_from_file(const std::string& filepath) {
46+
return read_json_from_file(filepath.c_str());
47+
}
48+
4649
Json read_json_from_stdin() {
4750
Json j;
4851
std::cin >> j;
@@ -77,6 +80,9 @@ Json read_json_with_interpolation(const std::string& filepath_or_stdin, const En
7780

7881
Conf read_conf_from_file(const char* filepath) { return Conf{std::string(filepath)}; }
7982

83+
Conf read_conf_from_file(const std::string& filepath) {
84+
return read_conf_from_file(filepath.c_str());
85+
}
8086
Conf read_conf_from_stdin() { return Conf{read_json_from_stdin()}; }
8187

8288
Conf read_conf(const std::string& filepath_or_stdin) {
@@ -96,7 +102,13 @@ Conf read_conf_with_interpolation(const std::string& filepath_or_stdin, const En
96102
}
97103

98104
std::string indent_string(std::string s, const std::string& indent) {
99-
boost::replace_all(s, "\n", "\n" + indent);
105+
std::string search = "\n";
106+
std::string replace = "\n" + indent;
107+
size_t pos = 0;
108+
while ((pos = s.find(search, pos)) != std::string::npos) {
109+
s.replace(pos, search.length(), replace);
110+
pos += replace.length();
111+
}
100112
return indent + s;
101113
}
102114

0 commit comments

Comments
 (0)