Last active
February 17, 2016 15:47
-
-
Save jslee02/37da0df5c954d7539888 to your computer and use it in GitHub Desktop.
const_ptr_vector
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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