Skip to content

Instantly share code, notes, and snippets.

@jslee02
Last active February 17, 2016 15:47
Show Gist options
  • Save jslee02/37da0df5c954d7539888 to your computer and use it in GitHub Desktop.
Save jslee02/37da0df5c954d7539888 to your computer and use it in GitHub Desktop.
const_ptr_vector
template <typename T>
class const_ptr_vector
{
public:
class iterator
{
public:
using const_iterator = typename std::vector<T*>::const_iterator;
iterator(const const_iterator& begin) : mIterater{begin} { }
iterator& operator++()
{
++mIterater;
return *this;
}
bool operator!=(const iterator& rhs) const
{
return mIterater != rhs.mIterater;
}
const T* operator*() const
{
return const_cast<const T*>(*mIterater);
}
protected:
const_iterator mIterater;
};
const_ptr_vector(const std::vector<T*>& container)
: mContainer(container) {}
// Element access
const T* operator[](size_t index)
{
return const_cast<const T*>(mContainer[index]);
// or,
// const auto& it = iterator(mContainer.begin() + index);
// return *it;
}
const T* operator[](size_t index) const
{
return const_cast<const T*>(mContainer[index]);
// or,
// const auto& it = iterator(mContainer.begin() + index);
// return *it;
}
// Iterators
iterator begin() const
{
return iterator(mContainer.cbegin());
}
iterator end() const
{
return iterator(mContainer.cend());
}
// Capacity
bool empty() const { return mContainer.empty(); }
size_t size() const { return mContainer.size(); }
protected:
const std::vector<T*>& mContainer;
};
template <typename Base, typename Derived>
class static_cast_vector
{
public:
class static_cast_iterator
{
public:
using iterator = typename std::vector<Base*>::iterator;
static_cast_iterator(const iterator& begin)
: mIterater{begin} { }
static_cast_iterator& operator++()
{
++mIterater;
return *this;
}
bool operator!=(const static_cast_iterator& rhs) const
{
return mIterater != rhs.mIterater;
}
const Derived* operator*() const
{
return static_cast<Derived*>(*mIterater);
}
Derived* operator*()
{
return static_cast<Derived*>(*mIterater);
}
protected:
iterator mIterater;
};
static_cast_vector(std::vector<Base*>& container)
: mContainer(container) {}
// Element access
Derived* operator[](size_t index)
{
return static_cast<Derived*>(mContainer[index]);
}
Derived* operator[](size_t index) const
{
return static_cast<Derived*>(mContainer[index]);
}
// Iterators
static_cast_iterator begin()
{
return static_cast_iterator(mContainer.begin());
}
static_cast_iterator end()
{
return static_cast_iterator(mContainer.end());
}
// Capacity
bool empty() const { return mContainer.empty(); }
size_t size() const { return mContainer.size(); }
protected:
std::vector<Base*>& mContainer;
};
#include <memory>
#include <gtest/gtest.h>
//==============================================================================
struct Base
{
Base() = default;
virtual ~Base() = default;
std::string print()
{
return "Base";
}
std::string print() const
{
return "const Base";
}
};
struct Derived : Base
{
Derived() = default;
virtual ~Derived() = default;
std::string print()
{
return "Derived";
}
std::string print() const
{
return "const Derived";
}
};
//==============================================================================
TEST(StlHelpers, CONST_PTR_VECTOR)
{
std::vector<Base*> vec{3};
for (auto ele : vec)
ele = new Base();
const_ptr_vector<Base> const_vec(vec);
EXPECT_EQ(vec[0]->print(), "Base");
EXPECT_EQ(const_vec[0]->print(), "const Base");
std::vector<Base*>::iterator it = vec.begin();
EXPECT_EQ((*it)->print(), "Base");
for(auto ele : vec)
EXPECT_EQ(ele->print(), "Base");
for(const auto ele : vec)
EXPECT_EQ(ele->print(), "Base");
for(auto i = 0u; i < vec.size(); ++i)
EXPECT_EQ(vec[i]->print(), "Base");
for(auto const_ele : const_vec)
EXPECT_EQ(const_ele->print(), "const Base");
for(const auto const_ele : const_vec)
EXPECT_EQ(const_ele->print(), "const Base");
for(auto i = 0u; i < const_vec.size(); ++i)
EXPECT_EQ(const_vec[i]->print(), "const Base");
for (auto ele : vec)
delete ele;
}
//==============================================================================
TEST(StlHelpers, STATIC_CAST_VECTOR)
{
std::vector<Base*> vec{3};
static_cast_vector<Base, Derived> derived_vec(vec);
EXPECT_EQ(vec[0]->print(), "Base");
EXPECT_EQ(derived_vec[0]->print(), "Derived");
std::vector<Base*>::iterator it = vec.begin();
EXPECT_EQ((*it)->print(), "Base");
for(auto ele : vec)
EXPECT_EQ(ele->print(), "Base");
for(auto i = 0u; i < vec.size(); ++i)
EXPECT_EQ(vec[i]->print(), "Base");
for(auto derived_ele : derived_vec)
EXPECT_EQ(derived_ele->print(), "Derived");
for(auto i = 0u; i < derived_vec.size(); ++i)
EXPECT_EQ(derived_vec[i]->print(), "Derived");
}
//==============================================================================
int main(int argc, char* argv[])
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment