Skip to content

Instantly share code, notes, and snippets.

@CyberDNIWE
Created November 15, 2022 09:10
Show Gist options
  • Save CyberDNIWE/c806ad3814ed7764f1537296a8a39e2f to your computer and use it in GitHub Desktop.
Save CyberDNIWE/c806ad3814ed7764f1537296a8a39e2f to your computer and use it in GitHub Desktop.
poorly::Iterable, make plain-c arrays "poorly" iterable
// poorly::Iterable: poor man's iterator provider that does not take ownership of underlying array
// Usage: copy-paste poorly namespace & use MAKE_POORLY_ITERABLE to make plain-c array iterable.
// (see examples for more info).
#pragma region COPY_PASTE_ITERABLE
#include <cstdint>
namespace poorly
{
template<typename T, size_t SIZE>
struct Iterable
{
using ConstPtr = T * const;
struct iterator
{
public:
constexpr iterator() noexcept : ptr(nullptr)
{}
constexpr iterator(T* p) noexcept : ptr(p)
{}
void begin(const Iterable& v) noexcept
{
ptr = v.m_dataPtr;
}
T& operator*() const noexcept
{
return *ptr;
}
const iterator& operator++() noexcept
{
++ptr;
return *this;
}
bool operator != (const iterator& other) const noexcept
{
return ptr != other.ptr;
}
private:
T* ptr;
};
public:
constexpr Iterable(ConstPtr first) : m_dataPtr(first)
{}
constexpr iterator begin() const
{
return { m_dataPtr };
}
constexpr const iterator end() const
{
return { m_dataPtr + SIZE };
}
private:
ConstPtr m_dataPtr = nullptr;
};
// These are here to deduce underlying types in case some wise guy decides to use mutlidim arrays
template<class T>
struct remove_all_extents
{ typedef T type; };
template<class T>
struct remove_all_extents<T[]>
{ typedef typename remove_all_extents<T>::type type; };
template<class T, size_t N>
struct remove_all_extents<T[N]>
{ typedef typename remove_all_extents<T>::type type; };
template<typename T, size_t SIZE>
constexpr size_t array_length(T(&)[SIZE]) { return SIZE; }
#ifndef MAKE_POORLY_ITERABLE
#define MAKE_POORLY_ITERABLE(arrname) poorly::Iterable<remove_all_extents<decltype(arrname)>::type, poorly::array_length(arrname)>(arrname)
#endif
};
#pragma endregion
#pragma region ints
#define A_FEW_TIMES size_t i = 0; i < 2; ++i
using namespace poorly;
constexpr int arr[] = { 1,2,3,4,5 };
void testWithInts() noexcept
{
auto iteratable = MAKE_POORLY_ITERABLE(arr);
///*
// Simple ranged for
for(const auto& v : iteratable)
{
int cur = v;
bool dbg3 = true;
}
//*/
// Create once, reuse multiple times- iterator approach
auto iter1 = iteratable.begin();
auto iter2 = iteratable.end();
for(A_FEW_TIMES)
{
for(; iter1 != iter2; ++iter1)
{
const int& cur = *iter1;
bool dbg3 = true;
}
//Reset iter1 without re-constructing
iter1.begin(iteratable);
}
}
#pragma endregion
#pragma region inheritance
// Stuff to test out class chierarcies
#pragma region stufftotestout
struct Base
{
constexpr Base() noexcept = default;
virtual ~Base() = default;
virtual void doStuff() const noexcept = 0;
};
class Derived : public Base
{
public:
Derived() noexcept = default;
~Derived() = default;
virtual void doStuff() const noexcept;
private:
};
#include <iostream>
void Derived::doStuff() const noexcept
{
std::cout << "Derived::doStuff() called" << '\n';
}
class OtherDerived : public Base
{
public:
constexpr OtherDerived() noexcept = default;
~OtherDerived() = default;
virtual void doStuff() const noexcept;
private:
};
void OtherDerived::doStuff() const noexcept
{
std::cout << "OtherDerived::doStuff() called" << '\n';
}
#pragma endregion
const Derived foo = {};
const OtherDerived bar = {};
const OtherDerived bar2 = {};
constexpr const Base* things[] = { &foo, &bar, &bar2 };
void testWithRuntumePolymorphism() noexcept
{
auto iterable = MAKE_POORLY_ITERABLE(things);
// Simple ranged for
for(const auto& thing : things)
{
thing->doStuff();
}
std::cout << '\n';
// Create once, use multiple times approach
auto cur = iterable.begin();
const auto end = iterable.end();
for(A_FEW_TIMES)
{
for(; cur != end; ++cur)
{
(*cur)->doStuff();
}
cur.begin(iterable);
std::cout << '\n';
}
}
#pragma endregion
int main()
{
///*
testWithInts();
//*/
///*
testWithRuntumePolymorphism();
//*/
std::getchar();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment