Commit 8cd8dfaa authored by Davis King's avatar Davis King

Switched the std_vector_c object to use inheritance so that casting between

std_vector_c and std::vector is more natural.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403384
parent 381cfb19
...@@ -17,10 +17,9 @@ namespace dlib ...@@ -17,10 +17,9 @@ namespace dlib
typename T, typename T,
typename Allocator = std::allocator<T> typename Allocator = std::allocator<T>
> >
class std_vector_c class std_vector_c : public std::vector<T,Allocator>
{ {
typedef typename std::vector<T,Allocator> base_type; typedef typename std::vector<T,Allocator> base_type;
base_type impl;
public: public:
// types: // types:
typedef typename Allocator::reference reference; typedef typename Allocator::reference reference;
...@@ -38,63 +37,53 @@ namespace dlib ...@@ -38,63 +37,53 @@ namespace dlib
// 23.2.4.1 construct/copy/destroy: // 23.2.4.1 construct/copy/destroy:
explicit std_vector_c(const Allocator& alloc= Allocator()) : impl(alloc) {} explicit std_vector_c(const Allocator& alloc= Allocator()) : base_type(alloc) {}
explicit std_vector_c(size_type n, const T& value = T(), explicit std_vector_c(size_type n, const T& value = T(),
const Allocator& alloc= Allocator()) : impl(n, value, alloc) {} const Allocator& alloc= Allocator()) : base_type(n, value, alloc) {}
template <typename InputIterator> template <typename InputIterator>
std_vector_c(InputIterator first, InputIterator last, std_vector_c(InputIterator first, InputIterator last,
const Allocator& alloc= Allocator()) : impl(first,last,alloc) {} const Allocator& alloc= Allocator()) : base_type(first,last,alloc) {}
std_vector_c(const std_vector_c<T,Allocator>& x) : impl(x.impl) {} std_vector_c(const std::vector<T,Allocator>& x) : base_type(x) {}
std_vector_c(const std::vector<T,Allocator>& x) : impl(x) {}
operator const base_type& () const { return impl; }
operator base_type& () { return impl; }
std_vector_c<T,Allocator>& operator=(const std_vector_c<T,Allocator>& x)
{
impl = x.impl;
return *this;
}
std_vector_c<T,Allocator>& operator=(const std::vector<T,Allocator>& x) std_vector_c<T,Allocator>& operator=(const std::vector<T,Allocator>& x)
{ {
impl = x; static_cast<base_type&>(*this) = x;
return *this; return *this;
} }
template <typename InputIterator> template <typename InputIterator>
void assign(InputIterator first, InputIterator last) { impl.assign(first,last); } void assign(InputIterator first, InputIterator last) { base_type::assign(first,last); }
void assign(size_type n, const T& u) { impl.assign(n,u); } void assign(size_type n, const T& u) { base_type::assign(n,u); }
allocator_type get_allocator() const { return impl.get_allocator(); } allocator_type get_allocator() const { return base_type::get_allocator(); }
// iterators: // iterators:
iterator begin() { return impl.begin(); } iterator begin() { return base_type::begin(); }
const_iterator begin() const { return impl.begin(); } const_iterator begin() const { return base_type::begin(); }
iterator end() { return impl.end(); } iterator end() { return base_type::end(); }
const_iterator end() const { return impl.end(); } const_iterator end() const { return base_type::end(); }
reverse_iterator rbegin() { return impl.rbegin(); } reverse_iterator rbegin() { return base_type::rbegin(); }
const_reverse_iterator rbegin() const { return impl.rbegin(); } const_reverse_iterator rbegin() const { return base_type::rbegin(); }
reverse_iterator rend() { return impl.rend(); } reverse_iterator rend() { return base_type::rend(); }
const_reverse_iterator rend() const { return impl.rend(); } const_reverse_iterator rend() const { return base_type::rend(); }
// 23.2.4.2 capacity: // 23.2.4.2 capacity:
size_type size() const { return impl.size(); } size_type size() const { return base_type::size(); }
size_type max_size() const { return impl.max_size(); } size_type max_size() const { return base_type::max_size(); }
void resize(size_type sz, T c = T()) { impl.resize(sz,c); } void resize(size_type sz, T c = T()) { base_type::resize(sz,c); }
size_type capacity() const { return impl.capacity(); } size_type capacity() const { return base_type::capacity(); }
bool empty() const { return impl.empty(); } bool empty() const { return base_type::empty(); }
void reserve(size_type n) { impl.reserve(n); } void reserve(size_type n) { base_type::reserve(n); }
// element access: // element access:
const_reference at(size_type n) const { return impl.at(n); } const_reference at(size_type n) const { return base_type::at(n); }
reference at(size_type n) { return impl.at(n); } reference at(size_type n) { return base_type::at(n); }
// 23.2.4.3 modifiers: // 23.2.4.3 modifiers:
void push_back(const T& x) { impl.push_back(x); } void push_back(const T& x) { base_type::push_back(x); }
void swap(std_vector_c<T,Allocator>& x) { impl.swap(x.impl); } void swap(std_vector_c<T,Allocator>& x) { base_type::swap(x); }
void clear() { impl.clear(); } void clear() { base_type::clear(); }
// ------------------------------------------------------ // ------------------------------------------------------
...@@ -112,7 +101,7 @@ namespace dlib ...@@ -112,7 +101,7 @@ namespace dlib
<< "\n\tn: " << n << "\n\tn: " << n
<< "\n\tsize(): " << size() << "\n\tsize(): " << size()
); );
return impl[n]; return static_cast<base_type&>(*this)[n];
} }
// ------------------------------------------------------ // ------------------------------------------------------
...@@ -128,7 +117,7 @@ namespace dlib ...@@ -128,7 +117,7 @@ namespace dlib
<< "\n\tn: " << n << "\n\tn: " << n
<< "\n\tsize(): " << size() << "\n\tsize(): " << size()
); );
return impl[n]; return static_cast<const base_type&>(*this)[n];
} }
// ------------------------------------------------------ // ------------------------------------------------------
...@@ -141,7 +130,7 @@ namespace dlib ...@@ -141,7 +130,7 @@ namespace dlib
<< "\n\tYou can't call front() on an empty vector" << "\n\tYou can't call front() on an empty vector"
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
return impl.front(); return base_type::front();
} }
// ------------------------------------------------------ // ------------------------------------------------------
...@@ -154,7 +143,7 @@ namespace dlib ...@@ -154,7 +143,7 @@ namespace dlib
<< "\n\tYou can't call front() on an empty vector" << "\n\tYou can't call front() on an empty vector"
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
return impl.front(); return base_type::front();
} }
// ------------------------------------------------------ // ------------------------------------------------------
...@@ -167,7 +156,7 @@ namespace dlib ...@@ -167,7 +156,7 @@ namespace dlib
<< "\n\tYou can't call back() on an empty vector" << "\n\tYou can't call back() on an empty vector"
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
return impl.back(); return base_type::back();
} }
// ------------------------------------------------------ // ------------------------------------------------------
...@@ -180,7 +169,7 @@ namespace dlib ...@@ -180,7 +169,7 @@ namespace dlib
<< "\n\tYou can't call back() on an empty vector" << "\n\tYou can't call back() on an empty vector"
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
return impl.back(); return base_type::back();
} }
// ------------------------------------------------------ // ------------------------------------------------------
...@@ -193,7 +182,7 @@ namespace dlib ...@@ -193,7 +182,7 @@ namespace dlib
<< "\n\tYou can't call pop_back() on an empty vector" << "\n\tYou can't call pop_back() on an empty vector"
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
impl.pop_back(); base_type::pop_back();
} }
// ------------------------------------------------------ // ------------------------------------------------------
...@@ -208,7 +197,7 @@ namespace dlib ...@@ -208,7 +197,7 @@ namespace dlib
<< "\n\tYou have called insert() with an invalid position" << "\n\tYou have called insert() with an invalid position"
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
return impl.insert(position, x); return base_type::insert(position, x);
} }
// ------------------------------------------------------ // ------------------------------------------------------
...@@ -224,7 +213,7 @@ namespace dlib ...@@ -224,7 +213,7 @@ namespace dlib
<< "\n\tYou have called insert() with an invalid position" << "\n\tYou have called insert() with an invalid position"
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
impl.insert(position, n, x); base_type::insert(position, n, x);
} }
// ------------------------------------------------------ // ------------------------------------------------------
...@@ -241,7 +230,7 @@ namespace dlib ...@@ -241,7 +230,7 @@ namespace dlib
<< "\n\tYou have called insert() with an invalid position" << "\n\tYou have called insert() with an invalid position"
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
impl.insert(position, first, last); base_type::insert(position, first, last);
} }
// ------------------------------------------------------ // ------------------------------------------------------
...@@ -255,7 +244,7 @@ namespace dlib ...@@ -255,7 +244,7 @@ namespace dlib
<< "\n\tYou have called erase() with an invalid position" << "\n\tYou have called erase() with an invalid position"
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
return impl.erase(position); return base_type::erase(position);
} }
// ------------------------------------------------------ // ------------------------------------------------------
...@@ -270,7 +259,7 @@ namespace dlib ...@@ -270,7 +259,7 @@ namespace dlib
<< "\n\tYou have called erase() with an invalid range of iterators" << "\n\tYou have called erase() with an invalid range of iterators"
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
return impl.erase(first,last); return base_type::erase(first,last);
} }
// ------------------------------------------------------ // ------------------------------------------------------
...@@ -280,33 +269,16 @@ namespace dlib ...@@ -280,33 +269,16 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// Add these swaps just to make absolutely sure the specialized swap always gets called even
// if the compiler is crappy and would otherwise mess it up.
template <typename T, typename Allocator> template <typename T, typename Allocator>
bool operator==(const std_vector_c<T,Allocator>& x, const std_vector_c<T,Allocator>& y) void swap(std_vector_c<T,Allocator>& x, std_vector_c<T,Allocator>& y) { x.swap(y); }
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
template <typename T, typename Allocator>
bool operator< (const std_vector_c<T,Allocator>& x, const std_vector_c<T,Allocator>& y)
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
template <typename T, typename Allocator>
bool operator!=(const std_vector_c<T,Allocator>& x, const std_vector_c<T,Allocator>& y)
{ return !(x == y); }
template <typename T, typename Allocator>
bool operator> (const std_vector_c<T,Allocator>& x, const std_vector_c<T,Allocator>& y)
{ return y < x; }
template <typename T, typename Allocator>
bool operator>=(const std_vector_c<T,Allocator>& x, const std_vector_c<T,Allocator>& y)
{ return !(x < y); }
template <typename T, typename Allocator> template <typename T, typename Allocator>
bool operator<=(const std_vector_c<T,Allocator>& x, const std_vector_c<T,Allocator>& y) void swap(std::vector<T,Allocator>& x, std_vector_c<T,Allocator>& y) { x.swap(y); }
{ return !(y < x); }
// specialized algorithms:
template <typename T, typename Allocator> template <typename T, typename Allocator>
void swap(std_vector_c<T,Allocator>& x, std_vector_c<T,Allocator>& y) { x.swap(y); } void swap(std_vector_c<T,Allocator>& x, std::vector<T,Allocator>& y) { y.swap(x); }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -14,7 +14,7 @@ namespace dlib ...@@ -14,7 +14,7 @@ namespace dlib
typename T, typename T,
typename Allocator = std::allocator<T> typename Allocator = std::allocator<T>
> >
class std_vector_c class std_vector_c : public std::vector<T,Allocator>
{ {
/*! /*!
WHAT THIS OBJECT REPRESENTS WHAT THIS OBJECT REPRESENTS
...@@ -75,14 +75,6 @@ namespace dlib ...@@ -75,14 +75,6 @@ namespace dlib
- std::equal(first, last, begin()) == true - std::equal(first, last, begin()) == true
!*/ !*/
std_vector_c(
const std_vector_c<T,Allocator>& x
);
/*!
ensures
- #*this == x
!*/
std_vector_c( std_vector_c(
const std::vector<T,Allocator>& x const std::vector<T,Allocator>& x
); );
...@@ -91,31 +83,6 @@ namespace dlib ...@@ -91,31 +83,6 @@ namespace dlib
- #*this == x - #*this == x
!*/ !*/
operator const std::vector<T,Allocator>& (
) const;
/*!
ensures
- returns a const reference to the normal unchecked std::vector
object contained inside *this
!*/
operator std::vector<T,Allocator>& (
);
/*!
ensures
- returns a non-const reference to the normal unchecked std::vector
object contained inside *this
!*/
std_vector_c<T,Allocator>& operator= (
const std_vector_c<T,Allocator>& x
);
/*!
ensures
- #*this == x
- returns #*this
!*/
std_vector_c<T,Allocator>& operator= ( std_vector_c<T,Allocator>& operator= (
const std::vector<T,Allocator>& x const std::vector<T,Allocator>& x
); );
...@@ -472,42 +439,6 @@ namespace dlib ...@@ -472,42 +439,6 @@ namespace dlib
}; };
// ----------------------------------------------------------------------------------------
// provide global comparison operators that work for the std_vector_c object.
template <typename T, typename Allocator>
bool operator==(const std_vector_c<T,Allocator>& x, const std_vector_c<T,Allocator>& y)
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
template <typename T, typename Allocator>
bool operator< (const std_vector_c<T,Allocator>& x, const std_vector_c<T,Allocator>& y)
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
template <typename T, typename Allocator>
bool operator!=(const std_vector_c<T,Allocator>& x, const std_vector_c<T,Allocator>& y)
{ return !(x == y); }
template <typename T, typename Allocator>
bool operator> (const std_vector_c<T,Allocator>& x, const std_vector_c<T,Allocator>& y)
{ return y < x; }
template <typename T, typename Allocator>
bool operator>=(const std_vector_c<T,Allocator>& x, const std_vector_c<T,Allocator>& y)
{ return !(x < y); }
template <typename T, typename Allocator>
bool operator<=(const std_vector_c<T,Allocator>& x, const std_vector_c<T,Allocator>& y)
{ return !(y < x); }
// ----------------------------------------------------------------------------------------
template <typename T, typename Allocator>
void swap(std_vector_c<T,Allocator>& x, std_vector_c<T,Allocator>& y) { x.swap(y); }
/*!
provides a global swap function
!*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T, typename alloc> template <typename T, typename alloc>
......
...@@ -74,6 +74,7 @@ set (tests ...@@ -74,6 +74,7 @@ set (tests
stack.cpp stack.cpp
static_map.cpp static_map.cpp
static_set.cpp static_set.cpp
std_vector_c.cpp
string.cpp string.cpp
svm.cpp svm.cpp
thread_pool.cpp thread_pool.cpp
......
...@@ -84,6 +84,7 @@ SRC += sockstreambuf.cpp ...@@ -84,6 +84,7 @@ SRC += sockstreambuf.cpp
SRC += stack.cpp SRC += stack.cpp
SRC += static_map.cpp SRC += static_map.cpp
SRC += static_set.cpp SRC += static_set.cpp
SRC += std_vector_c.cpp
SRC += string.cpp SRC += string.cpp
SRC += svm.cpp SRC += svm.cpp
SRC += thread_pool.cpp SRC += thread_pool.cpp
......
// Copyright (C) 2010 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#include <sstream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <dlib/stl_checked.h>
#include "tester.h"
// This is called an unnamed-namespace and it has the effect of making everything inside this file "private"
// so that everything you declare will have static linkage. Thus we won't have any multiply
// defined symbol errors coming out of the linker when we try to compile the test suite.
namespace
{
using namespace test;
using namespace dlib;
using namespace std;
// Declare the logger we will use in this test. The name of the tester
// should start with "test."
logger dlog("test.std_vector_c");
class std_vector_c_tester : public tester
{
/*!
WHAT THIS OBJECT REPRESENTS
This object represents a test for the std_vector_c object. When it is constructed
it adds itself into the testing framework. The command line switch is
specified as test_std_vector_c by passing that string to the tester constructor.
!*/
public:
std_vector_c_tester (
) :
tester ("test_std_vector_c",
"Runs tests on the std_vector_c component.")
{}
void perform_test (
)
{
std::vector<int> c;
std_vector_c<int> a, b;
a.push_back(3);
a.push_back(2);
a.push_back(1);
DLIB_TEST(a[0] == 3);
DLIB_TEST(a[1] == 2);
DLIB_TEST(a[2] == 1);
c = a;
DLIB_TEST(c[0] == 3);
DLIB_TEST(c[1] == 2);
DLIB_TEST(c[2] == 1);
DLIB_TEST(c.size() == 3);
DLIB_TEST(a.size() == 3);
DLIB_TEST(b.size() == 0);
DLIB_TEST(a == c);
DLIB_TEST(!(a != c));
DLIB_TEST(a <= c);
DLIB_TEST(a >= c);
DLIB_TEST(!(a < c));
DLIB_TEST(!(a > c));
swap(b,c);
DLIB_TEST(b[0] == 3);
DLIB_TEST(b[1] == 2);
DLIB_TEST(b[2] == 1);
DLIB_TEST(c.size() == 0);
DLIB_TEST(b.size() == 3);
swap(c,b);
DLIB_TEST(c[0] == 3);
DLIB_TEST(c[1] == 2);
DLIB_TEST(c[2] == 1);
DLIB_TEST(c.size() == 3);
DLIB_TEST(b.size() == 0);
swap(a,b);
DLIB_TEST(b[0] == 3);
DLIB_TEST(b[1] == 2);
DLIB_TEST(b[2] == 1);
DLIB_TEST(b.size() == 3);
DLIB_TEST(a.size() == 0);
swap(b,c);
swap(c,c);
std_vector_c<int> h(a);
std_vector_c<int> i(c);
std::vector<int> j(b);
}
} a;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment