string: allow tokenisation of c arrays
This commit is contained in:
parent
9c5b471b24
commit
cfa272a80a
40
string.hpp
40
string.hpp
@ -40,7 +40,20 @@ namespace util {
|
|||||||
|
|
||||||
tokeniser (Iterator first, Iterator last, value_type separator);
|
tokeniser (Iterator first, Iterator last, value_type separator);
|
||||||
|
|
||||||
struct iterator {
|
template <typename ContainerT>
|
||||||
|
tokeniser (ContainerT &container, typename ContainerT::value_type _separator):
|
||||||
|
tokeniser (
|
||||||
|
std::begin (container),
|
||||||
|
std::end (container),
|
||||||
|
_separator
|
||||||
|
)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
struct iterator : public std::iterator<
|
||||||
|
std::forward_iterator_tag,
|
||||||
|
range_type,
|
||||||
|
std::size_t
|
||||||
|
> {
|
||||||
public:
|
public:
|
||||||
iterator operator++ (int);
|
iterator operator++ (int);
|
||||||
iterator& operator++ (void)&;
|
iterator& operator++ (void)&;
|
||||||
@ -72,9 +85,28 @@ namespace util {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
tokeniser<std::string::const_iterator> make_tokeniser (const std::string&, std::string::value_type);
|
///////////////////////////////////////////////////////////////////////////
|
||||||
tokeniser<std::string::const_iterator> make_tokeniser (std::string&&, std::string::value_type) = delete;
|
template <typename CharT, std::size_t LengthV>
|
||||||
tokeniser<const char*> make_tokeniser (const char*, char);
|
auto
|
||||||
|
make_tokeniser (CharT (&data)[LengthV], CharT separator)
|
||||||
|
{
|
||||||
|
return tokeniser { std::begin (data), std::end (data), separator };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
tokeniser<std::string::const_iterator>
|
||||||
|
make_tokeniser (const std::string&, std::string::value_type);
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
tokeniser<std::string::const_iterator>
|
||||||
|
make_tokeniser (std::string&&, std::string::value_type) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
tokeniser<const char*>
|
||||||
|
make_tokeniser (const char*, char);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#include "tap.hpp"
|
#include "tap.hpp"
|
||||||
#include "string.hpp"
|
#include "string.hpp"
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
#include "iterator.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int, char**)
|
main (int, char**)
|
||||||
@ -8,28 +11,23 @@ main (int, char**)
|
|||||||
util::TAP::logger tap;
|
util::TAP::logger tap;
|
||||||
|
|
||||||
const char csv[] = "\0,a,123,,this is a test,";
|
const char csv[] = "\0,a,123,,this is a test,";
|
||||||
const std::string values[] = {
|
|
||||||
{ "\0", 1 },
|
// expected test data must be a std::string so we can check embedded
|
||||||
{ "a" },
|
// nulls (which are ambiguous when using a cstr).
|
||||||
{ "123" },
|
struct foo {
|
||||||
{ "" },
|
const std::string value;
|
||||||
{ "this is a test" },
|
const char *message;
|
||||||
{ "" }
|
} TESTS[] = {
|
||||||
|
{ "\0", "null" },
|
||||||
|
{ "a", "single letter" },
|
||||||
|
{ "123", "three digits" },
|
||||||
|
{ "", "empty string" },
|
||||||
|
{ "this is a test", "string with spaces" },
|
||||||
|
{ "", "trailing empty" }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string str (std::cbegin (csv), std::cbegin (csv) + std::size (csv));
|
for (const auto &[tok, expected]: util::zip (util::make_tokeniser (csv, ','), TESTS))
|
||||||
auto tok = util::make_tokeniser (str, ',');
|
tap.expect (equal (tok, expected.value), "%s", expected.message);
|
||||||
auto t_cursor = tok.cbegin ();
|
|
||||||
auto v_cursor = std::cbegin (values);
|
|
||||||
|
|
||||||
tap.expect_eq (*t_cursor++, *v_cursor++, "tokeniser, single letter");
|
|
||||||
tap.expect_eq (*t_cursor++, *v_cursor++, "tokeniser, three digits");
|
|
||||||
tap.expect_eq (*t_cursor++, *v_cursor++, "tokeniser, embedded null");
|
|
||||||
tap.expect_eq (*t_cursor++, *v_cursor++, "tokeniser, empty string");
|
|
||||||
tap.expect_eq (*t_cursor++, *v_cursor++, "tokeniser, string with spaces");
|
|
||||||
tap.expect_eq (*t_cursor++, *v_cursor++, "tokeniser, trailing empty");
|
|
||||||
|
|
||||||
tap.expect_eq (t_cursor, tok.cend (), "tokeniser iterator at end");
|
|
||||||
|
|
||||||
return tap.status ();
|
return tap.status ();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user