view: template on arbirtrary iterator types
This commit is contained in:
parent
905f4de303
commit
37f9390ef8
36
test/uri.cpp
36
test/uri.cpp
@ -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 ();
|
||||
}
|
||||
|
@ -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 ();
|
||||
|
6
uri.hpp
6
uri.hpp
@ -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;
|
||||
};
|
||||
|
||||
|
72
view.cpp
72
view.cpp
@ -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*>;
|
||||
|
29
view.hpp
29
view.hpp
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user