On Wednesday, January 6, 2021 at 3:52:46 AM UTC-5, Jorgen Grahn wrote:
> But I don't see what's wrong with this alternate chain of events:
>
> - I want basic_string_view.
> - Boost has one implementation.
> - All systems I target have a non-broken Boost (or if they don't,
> the users have problems already).
> - I'll depend on Boost and use boost::string_view (or whatever it's
> called) until I can drop support for C++ versions without
> std::string_view.
> - I'll assume Boost has been tested.
>
> You didn't AFAICT write about that option, although it seems like the
> obvious one.
Perspectives differ. But my perspective is that among the biggest
concerns for potential users of a C++ library are dependency management
and integration into other build systems. Both become more difficult
when the library has dependencies on other libraries.
Suppose all users do have boost. And suppose the library also
uses boost. It's still improbable that both were tested with the same
version of boost.
Keep in mind that popular open source libraries typically follow
this pattern: they have a period of great activity and outstanding support
while their creator has energy, followed by a longer period of inactivity
and abandoned issue tracking when their creator gets tired and loses
interest. The library Öö Tiib referred to - rapidjson - is an example of that.
Its last release was five years ago, and one of its 429 open issues is
"Too many open Issues!" Suppose rapidjson had used boost internally
(it doesn't): what are the chances that it would have compiled cleanly
with a recent version of boost? Another popular JSON library from the
time of rapidjson, JSON Spirit, was based on boost spirit. One of its last
unanswered issues, raised in Aug 2018, was: "Trying to rebuild with latest
boost 1.61 I end up with the following errors:"
That said, I'd certainly agree that users, while unlikely to care about
the types a library uses internally, would prefer to use the types
they've standardized on themselves if those types spill over into the
public interface. Libraries can accommodate that in a number of ways.
A common approach is
#if defined(THELIB_HAS_BOOST_OPTIONAL)
#include <boost/optional.hpp>
namespace thelib {
using boost::optional;
}
#elif defined(THELIB_HAS_STD_OPTIONAL)
#include <optional>
namespace thelib {
using std::optional;
}
#else // use internal implementation
#endif // !defined(THELIB_HAS_STD_OPTIONAL)
where there is usually an attempt to detect THELIB_HAS_STD_OPTIONAL,
and the user has the option to set THELIB_HAS_BOOST_OPTIONAL.
Another approach is to support code like
auto sv =
j.as<foo::string_view>();
or
auto j = json::parse(sv);
for types foo::string_view that the library doesn't know about, but
that satisfy certain type requirements.
>
> I wanted optional<T> > recently, but ended up implementing the parts
> I needed instead of requiring Boost or a recent-ish C++.
In my opinion, optional<T> is actually interesting as an implementation
exercise, as opposed to basic_string_view, which is mostly trivial. For an
intermediate level course in C++, it would make for an excellent assignment,
being of modest difficulty, and requiring an understanding of sfinae and
ref qualifiers. It's a good entry point into understanding how to implement
types along the lines of types found in standard library or boost headers,
whose code at first (or second) glance may seem somewhat obfuscated.
Daniel