Skip to content

Commit

Permalink
Update API documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
eliaskosunen committed Jan 10, 2024
1 parent 24c0b3e commit e227010
Show file tree
Hide file tree
Showing 12 changed files with 207 additions and 100 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ Although, that version is unlikely to get updates.
The documentation can be found online, from https://v2.scnlib.dev.

To build the docs yourself, build the `scn_docs` target generated by CMake.
These targets are generated only if the variable `SCN_DOCS` is set in CMake (
done automatically if scnlib is the root project).
These targets are generated only if the variable `SCN_DOCS` is set in CMake
(done automatically if scnlib is the root project).
The `scn_docs` target requires Doxygen, Python 3.8 or better, and the `pip3`
package `poxy`.

Expand Down Expand Up @@ -318,7 +318,7 @@ Lower is better.
Size of `scnlib` shared library (`.so`): 1.4M

| Method | Executable size | Stripped size |
| :------------- | --------------: | ------------: |
|:---------------|----------------:|--------------:|
| empty | 16.1 | 14.6 |
| `std::scanf` | 17.4 | 14.8 |
| `std::istream` | 17.8 | 14.8 |
Expand All @@ -331,7 +331,7 @@ Size of `scnlib` shared library (`.so`): 1.4M
Size of `scnlib` shared library (`.so`): 1.1M

| Method | Executable size | Stripped size |
| :------------- | --------------: | ------------: |
|:---------------|----------------:|--------------:|
| empty | 16.1 | 14.6 |
| `std::scanf` | 17.3 | 14.8 |
| `std::istream` | 17.7 | 14.8 |
Expand All @@ -344,7 +344,7 @@ Size of `scnlib` shared library (`.so`): 1.1M
Size of `scnlib` shared library (`.so`): 19M

| Method | Executable size | Stripped size |
| :------------- | --------------: | ------------: |
|:---------------|----------------:|--------------:|
| empty | 25.6 | 14.6 |
| `std::scanf` | 569 | 26.9 |
| `std::istream` | 527 | 18.8 |
Expand Down
3 changes: 1 addition & 2 deletions include/scn/detail/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@
#define SCN_USE_STD_RANGES 1
#endif

// TODO
#if 0
// SCN_USE_DYNAMIC_ALLOCATION
// TODO: SCN_USE_DYNAMIC_ALLOCATION
// If 0, removes all instances of dynamic allocation from the library,
// including references to standard facilities that may allocate.
#ifndef SCN_USE_DYNAMIC_ALLOCATION
Expand Down
14 changes: 12 additions & 2 deletions include/scn/detail/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ namespace scn {
template <typename CharT, typename Args>
struct scan_context_base {
public:
/// Get argument at index `id`
constexpr auto arg(size_t id) const SCN_NOEXCEPT
{
return m_args.get(id);
Expand Down Expand Up @@ -114,23 +115,32 @@ namespace scn {
basic_scan_context& operator=(basic_scan_context&&) = default;
~basic_scan_context() = default;

/// Get argument at index `id`
/**
* Returns an iterator pointing to the current position in the source
* range.
*/
constexpr iterator begin() const
{
return m_current;
}

/**
* Returns a sentinel pointing to the end of the source range.
*/
constexpr sentinel end() const
{
return ranges_std::default_sentinel;
}

/**
* Returns a subrange over `[begin(), end())`
*/
constexpr auto range() const
{
return ranges::subrange{begin(), end()};
}

/// Advances the beginning of the input range to `it`
/// Advances the beginning of the source range to `it`
void advance_to(iterator it)
{
m_current = SCN_MOVE(it);
Expand Down
40 changes: 39 additions & 1 deletion include/scn/detail/input_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,45 @@
namespace scn {
SCN_BEGIN_NAMESPACE

/// Tag type to indicate an invalid range given to `scn::scan`
/**
* \defgroup scannable Scannable sources
*
* \brief Description of the `scannable_range` and `scannable_source`
* concepts.
*
* A range is considered scannable, if it models at least `forward_range`,
* and its character type is correct (its value type is the same as the one
* of the format string).
* If the range additionally models `contiguous_range` and `sized_range`,
* additional optimizations are enabled.
*
* \code{.cpp}
* // Exposition only
* template <typename Range, typename CharT>
* concept scannable_range =
* ranges::forward_range<Range> &&
* std::same_as<ranges::range_value_t<Range>, CharT>;
* \endcode
*
* Additionally, files (`std::FILE*`) can be scanned from.
* Files are always considered to be narrow (`char`-oriented).
* Thus, the entire concept is:
*
* \code{.cpp}
* // Exposition only
* template <typename Source, typename CharT>
* concept scannable_source =
* (std::same_as<std::remove_cvref_t<Source>, std::FILE*> &&
* std::same_as<CharT, char>) ||
* scannable_range<Source, CharT>;
* \endcode
*/

/**
* Tag type to indicate an invalid range given to `scn::scan`
*
* \ingroup scannable
*/
struct invalid_input_range {};

struct invalid_char_type : invalid_input_range {};
Expand Down
11 changes: 7 additions & 4 deletions include/scn/detail/ranges.h
Original file line number Diff line number Diff line change
Expand Up @@ -456,12 +456,15 @@ namespace scn {
};
template <typename R>
struct borrowed_subrange_with_sentinel<R, false> {
using type = std::conditional_t<
std::is_same_v<detail::remove_cvref_t<R>, std::FILE*>,
std::FILE*,
ranges::dangling>;
using type = ranges::dangling;
};

/// Equivalent to
/// `ranges::subrange<ranges::iterator_t<R>, ranges::sentinel_t<R>>`
/// if `R` is a `borrowed_range`, and `ranges::dangling` otherwise.
///
/// Similar to `ranges::borrowed_subrange_t<R>`, expect this preserves
/// the range sentinel.
template <typename R>
using borrowed_subrange_with_sentinel_t =
typename borrowed_subrange_with_sentinel<R>::type;
Expand Down
19 changes: 19 additions & 0 deletions include/scn/detail/regex.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
namespace scn {
SCN_BEGIN_NAMESPACE

/**
* A single (sub)expression match.
*/
template <typename CharT>
class basic_regex_match {
public:
Expand All @@ -42,6 +45,7 @@ namespace scn {
}
#endif

/// Matched string
std::basic_string_view<CharT> get() const
{
return m_str;
Expand All @@ -57,6 +61,7 @@ namespace scn {
}

#if SCN_REGEX_SUPPORTS_NAMED_CAPTURES
/// The name of this capture, if any.
std::optional<std::basic_string_view<CharT>> name() const
{
return m_name;
Expand All @@ -71,6 +76,20 @@ namespace scn {
#endif
};

/**
* Can be used to get all subexpression captures of a regex match.
* Interface similar to
* `std::vector<std::optional<basic_regex_match<CharT>>>`.
*
* \code{.cpp}
* auto result =
* scn::scan<scn::regex_matches>("abc123", "{:/[(a-z]+)([0-9]+)/}");
* // result->value() has three elements:
* // [0]: "abc123" (entire match)
* // [1]: "abc" (first subexpression match)
* // [2]: "123" (second subexpression match)
* \endcode
*/
template <typename CharT>
class basic_regex_matches
: private std::vector<std::optional<basic_regex_match<CharT>>> {
Expand Down
23 changes: 22 additions & 1 deletion include/scn/detail/result.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,18 @@ namespace scn {
{
}

/// Access the ununsed input range
/// Access the ununsed source range
range_type range() const
{
return m_range;
}

/// The beginning of the unused source range
auto begin() const
{
return ranges::begin(m_range);
}
/// The end of the unused source range
auto end() const
{
return ranges::end(m_range);
Expand All @@ -150,6 +152,7 @@ namespace scn {

constexpr scan_result_file_storage(std::FILE* f) : m_file(f) {}

/// File used for scanning
range_type range() const
{
return m_file;
Expand Down Expand Up @@ -180,6 +183,15 @@ namespace scn {
return {};
}

ranges::dangling begin() const
{
return {};
}
ranges::dangling end() const
{
return {};
}

protected:
template <typename... Args>
void assign_range(Args&&...)
Expand All @@ -203,9 +215,14 @@ namespace scn {
}
}

#if !SCN_DOXYGEN
template <typename Range>
using scan_result_base =
typename decltype(get_scan_result_base<Range>())::type;
#else
template <typename Range>
using scan_result_base = scan_result_range_storage<Range>;
#endif
} // namespace detail

/**
Expand All @@ -217,6 +234,10 @@ namespace scn {
* type `scn::scan_result`, wrapped inside a `scn::scan_expected`.
*/

/**
* Type returned by `scan`, contains the unused input as a subrange, and the
* scanned values in a tuple.
*/
template <typename Range, typename... Args>
class scan_result : public detail::scan_result_base<Range>,
public detail::scan_result_value_storage<Args...> {
Expand Down
34 changes: 16 additions & 18 deletions include/scn/detail/scan.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@ namespace scn {
*
* Example:
* \code{.cpp}
* auto args = scn::make_scan_args<Range, Args...>();
* auto result = scn::vscan(std::forward<Range>(range), format, args);
* auto args = scn::make_scan_args<Source, Args...>();
* auto result = scn::vscan(std::forward<Source>(source), format, args);
*
* return scn::make_scan_result(std::move(result), std::move(args));
* \endcode
*
* \ingroup result
*/
template <typename ResultRange, typename Context, typename... Args>
auto make_scan_result(scan_expected<ResultRange>&& result,
template <typename Result, typename Context, typename... Args>
auto make_scan_result(scan_expected<Result>&& result,
scan_arg_store<Context, Args...>&& args)
-> scan_expected<scan_result<ResultRange, Args...>>
-> scan_expected<scan_result<Result, Args...>>
{
if (SCN_UNLIKELY(!result)) {
return unexpected(result.error());
Expand All @@ -59,12 +59,12 @@ namespace scn {
}

/**
* The return type of `scan`, based on the type of the input range, and the
* The return type of `scan`, based on the type of the source, and the
* types of the scanned arguments.
*/
template <typename Range, typename... Args>
template <typename Source, typename... Args>
using scan_result_type = scan_expected<
scan_result<borrowed_subrange_with_sentinel_t<Range>, Args...>>;
scan_result<detail::scan_result_value_type<Source>, Args...>>;

namespace detail {
// Boilerplate for scan()
Expand Down Expand Up @@ -92,12 +92,12 @@ namespace scn {
* The following functions use a format string syntax similar to that of
* `std::format`. See more at \ref format-string.
*
* When these functions take a range `source` as input, that range must
* model the `scannable_range` concept. See more at \ref scannable.
* When these functions take a `source` as input, it must
* model the `scannable_source` concept. See more at \ref scannable.
*/

/**
* Scans `Args...` from the range given to it (`source`), according to the
* Scans `Args...` from `source`, according to the
* specifications given in the format string (`format`).
* Returns the resulting values in an object of type `scan_result`,
* alongside a `subrange` pointing to the unused input.
Expand All @@ -123,7 +123,7 @@ namespace scn {
/**
* `scan` with explicitly supplied default values
*
* Can be used, for example, for preallocating a scanned string:
* Can be used, for example, for pre-allocating a scanned string:
*
* \code{.cpp}
* std::string str;
Expand Down Expand Up @@ -274,11 +274,9 @@ namespace scn {
}

/**
* Scan from stdin.
* Scan from `stdin`.
*
* Prefer this over constructing a view over `std::cin`,
* and using `scan` with it: `input` deals with synchronization with `stdin`
* and `std::cin`, and with multiple threads.
* Equivalent to `scn::scan<...>(stdin, ...)`.
*
* \code{.cpp}
* auto result = scn::input<int>("{}");
Expand Down Expand Up @@ -323,7 +321,7 @@ namespace scn {
/**
* Fast integer reading.
*
* Quickly reads an integer from a std::string_view. Skips preceding
* Quickly reads an integer from a `std::string_view`. Skips preceding
* whitespace.
*
* Reads in the specified base,
Expand All @@ -349,7 +347,7 @@ namespace scn {
/**
* Very fast integer reading.
*
* Quickly reads an integer from a std::string_view.
* Quickly reads an integer from a `std::string_view`.
*
* Be very careful when using this one!
* Its speed comes from some very heavy assumptions about the validity of
Expand Down
Loading

0 comments on commit e227010

Please sign in to comment.