view: template on arbirtrary iterator types

This commit is contained in:
Danny Robson 2015-09-21 15:36:05 +10:00
parent 905f4de303
commit 37f9390ef8
5 changed files with 71 additions and 81 deletions

View File

@ -6,6 +6,8 @@
int
main (void)
{
util::TAP::logger tap;
static const struct {
const char *src;
const char *scheme;
@ -14,26 +16,26 @@ main (void)
const char *query;
const char *fragment;
} GOOD[] = {
{ "ftp://ftp.is.co.za/rfc/rfc1808.txt", "ftp", "ftp.is.co.za", "/rfc/rfc1808.txt", "", "" },
{ "http://www.ietf.org/rfc/rfc2396.txt", "http", "www.ietf.org", "/rfc/rfc2396.txt", "", "" },
{ "ldap://[2001:db8::7]/c=GB?objectClass?one", "ldap", "[2001:db8::7]", "/c=GB", "objectClass?one", "" },
{ "mailto:John.Doe@example.com", "mailto", "", "John.Doe@example.com", "", "" },
{ "news:comp.infosystems.www.servers.unix", "news", "", "comp.infosystems.www.servers.unix", "", "" },
{ "tel:+1-816-555-1212", "tel", "", "+1-816-555-1212", "", "" },
{ "telnet://192.0.2.16:80/", "telnet", "192.0.2.16:80", "/", "", "" },
{ "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", "urn", "", "oasis:names:specification:docbook:dtd:xml:4.1.2", "", "" },
{ "ftp://ftp.is.co.za/rfc/rfc1808.txt", "ftp", "ftp.is.co.za", "/rfc/rfc1808.txt", "", "" },
{ "http://www.ietf.org/rfc/rfc2396.txt", "http", "www.ietf.org", "/rfc/rfc2396.txt", "", "" },
{ "ldap://[2001:db8::7]/c=GB?objectClass?one", "ldap", "[2001:db8::7]", "/c=GB", "objectClass?one", "" },
{ "mailto:John.Doe@example.com", "mailto", "", "John.Doe@example.com", "", "" },
{ "news:comp.infosystems.www.servers.unix", "news", "", "comp.infosystems.www.servers.unix", "", "" },
{ "tel:+1-816-555-1212", "tel", "", "+1-816-555-1212", "", "" },
{ "telnet://192.0.2.16:80/", "telnet", "192.0.2.16:80", "/", "", "" },
{ "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", "urn", "", "oasis:names:specification:docbook:dtd:xml:4.1.2", "", "" },
};
for (auto i: GOOD) {
CHECK_NOTHROW (util::uri foo (i.src));
tap.expect_nothrow ([i] (void) { util::uri foo (i.src); }, "nothrow parsing '%s'", i.src);
util::uri u (i.src);
CHECK_EQ (i.scheme, u.get (util::uri::SCHEME));
CHECK_EQ (i.authority, u.get (util::uri::AUTHORITY));
CHECK_EQ (i.path, u.get (util::uri::PATH));
CHECK_EQ (i.query, u.get (util::uri::QUERY));
CHECK_EQ (i.fragment, u.get (util::uri::FRAGMENT));
tap.expect (std::equal (u.get (util::uri::SCHEME).begin (), u.get (util::uri::SCHEME).end (), i.scheme), "extracting scheme for '%s'", i.src);
tap.expect (std::equal (u.get (util::uri::AUTHORITY).begin (), u.get (util::uri::AUTHORITY).end (), i.authority), "extracting authority '%s'", i.src);
tap.expect (std::equal (u.get (util::uri::PATH).begin (), u.get (util::uri::PATH).end (), i.path), "extracting path '%s'", i.src);
tap.expect (std::equal (u.get (util::uri::QUERY).begin (), u.get (util::uri::QUERY).end (), i.query), "extracting query '%s'", i.src);
tap.expect (std::equal (u.get (util::uri::FRAGMENT).begin (), u.get (util::uri::FRAGMENT).end (), i.fragment), "extracting fragment '%s'", i.src);
}
static const char* BAD[] = {
@ -41,8 +43,8 @@ main (void)
};
for (auto i: BAD)
CHECK_THROWS (util::uri::parse_error, util::uri foo (i));
tap.expect_throw<util::uri::parse_error> ([i] (void) { util::uri foo (i); }, "throw parsing '%s'", i);
util::TAP::logger tap;
tap.skip ("convert to TAP");
return tap.status ();
}

View File

@ -169,8 +169,13 @@ util::uri::uri (const char *first, const char *last):
{ ; }
///////////////////////////////////////////////////////////////////////////////
static const util::view<const char*> NULL_VIEW { nullptr, nullptr };
//-----------------------------------------------------------------------------
util::uri::uri (std::string &&_value):
m_views {NULL_VIEW, NULL_VIEW, NULL_VIEW, NULL_VIEW, NULL_VIEW},
m_value (std::move (_value))
{
const char *p = m_value.data ();
@ -190,7 +195,7 @@ util::uri::uri (std::string &&_value):
//-----------------------------------------------------------------------------
util::view
util::view<const char*>
util::uri::get (util::uri::component c)
{
CHECK_NEQ (c, NUM_COMPONENTS);
@ -217,7 +222,7 @@ hex_to_uint (char c)
//-----------------------------------------------------------------------------
std::string
util::uri::percent_decode (view s)
util::uri::percent_decode (view<const char*> s)
{
if (s.size () == 0)
return std::string ();

View File

@ -44,12 +44,12 @@ namespace util {
NUM_COMPONENTS
};
view get (component);
view<const char*> get (component);
static std::string percent_decode (view);
static std::string percent_decode (view<const char*>);
private:
view m_views[NUM_COMPONENTS];
view<const char*> m_views[NUM_COMPONENTS];
std::string m_value;
};

View File

@ -22,65 +22,57 @@
#include <cstring>
#include <iterator>
//-----------------------------------------------------------------------------
util::view::view ():
m_begin (nullptr),
m_end (nullptr)
{ ; }
using util::view;
//-----------------------------------------------------------------------------
util::view::view (const char *str):
m_begin (str),
m_end (str + strlen (str))
{ ; }
//-----------------------------------------------------------------------------
util::view::view (const char *_begin,
const char *_end):
template <typename T>
view<T>::view (T _begin, T _end):
m_begin (_begin),
m_end (_end)
{ ; }
//-----------------------------------------------------------------------------
const char*
util::view::begin (void) const
template <typename T>
T
view<T>::begin (void)
{
return m_begin;
}
//-----------------------------------------------------------------------------
const char*
util::view::end (void) const
template <typename T>
T
view<T>::end (void)
{
return m_end;
}
//-----------------------------------------------------------------------------
template <typename T>
bool
util::view::view::empty (void) const
view<T>::empty (void) const
{
return m_begin == nullptr ||
m_end == nullptr ||
m_begin == m_end;
return m_begin == m_end;
}
//-----------------------------------------------------------------------------
template <typename T>
size_t
util::view::size (void) const
view<T>::size (void) const
{
return m_end - m_begin;
return std::distance (m_begin, m_end);
}
//-----------------------------------------------------------------------------
const char&
util::view::operator[] (size_t idx) const
template <typename T>
const typename view<T>::value_type&
view<T>::operator[] (size_t idx) const
{
CHECK_LT (m_begin + idx, m_end);
return m_begin[idx];
@ -88,34 +80,24 @@ util::view::operator[] (size_t idx) const
//-----------------------------------------------------------------------------
template <typename T>
bool
util::view::operator== (const char *restrict rhs) const
view<T>::operator== (const view<T> rhs) const
{
return strlen (rhs) == size () &&
0 == strncmp (rhs, m_begin, size ());
}
//-----------------------------------------------------------------------------
bool
util::view::operator== (view v) const
{
return std::equal (m_begin, m_end, v.begin ());
return rhs.m_begin == m_begin &&
rhs.m_end == m_end;
}
//-----------------------------------------------------------------------------
template <typename T>
std::ostream&
util::operator<< (std::ostream &os, util::view s)
util::operator<< (std::ostream &os, util::view<T> v)
{
std::copy (s.begin (), s.end (), std::ostream_iterator<char> (os));
std::copy (v.begin (), v.end (), std::ostream_iterator<char> (os));
return os;
}
//-----------------------------------------------------------------------------
bool
util::operator== (const char *str, view v)
{
return v == str;
}
///////////////////////////////////////////////////////////////////////////////
template struct util::view<const char*>;

View File

@ -22,29 +22,30 @@
#include <iostream>
namespace util {
class view {
template <typename T>
struct view {
public:
view ();
explicit view (const char *str);
view (const char *first, const char *last);
using value_type = typename std::iterator_traits<T>::value_type;
const char *begin (void) const;
const char *end (void) const;
view (T first, T last);
bool empty () const;
T begin (void);
T end (void);
bool empty (void) const;
size_t size (void) const;
const char& operator[] (size_t) const;
bool operator== (const char *restrict str) const;
value_type& operator[] (size_t);
const value_type& operator[] (size_t) const;
bool operator== (view) const;
private:
const char *m_begin;
const char *m_end;
T m_begin;
T m_end;
};
std::ostream& operator<< (std::ostream&, view);
bool operator== (const char*, view);
template <typename T>
std::ostream& operator<< (std::ostream&, view<T>);
}
#endif