Skip to content

Commit

Permalink
Improve the Ponder API (#93)
Browse files Browse the repository at this point in the history
- ponder::classes(), Class::functions(), & Class::properties().
- Add View class.
  • Loading branch information
billyquith committed Dec 3, 2020
1 parent 467f097 commit 065121e
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 64 deletions.
15 changes: 9 additions & 6 deletions include/ponder/class.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class PONDER_API Class : public Type
Destructor m_destructor; // Destructor (function able to delete an abstract object)
UserObjectCreator m_userObjectCreator; // Convert pointer of class instance to UserObject

public: // declaration
public: // declaration

/**
* \brief Declare a new metaclass
Expand Down Expand Up @@ -147,7 +147,10 @@ class PONDER_API Class : public Type
template <typename T>
static void undeclare();

public: // reflection
public: // reflection

typedef View<const Function&, FunctionTable::const_iterator> FunctionView;
typedef View<const Property&, PropertyTable::const_iterator> PropertyView;

/**
* \brief Return the name of the metaclass
Expand Down Expand Up @@ -241,11 +244,11 @@ class PONDER_API Class : public Type
* \return An iterator that can be used to iterator over all functions
*
* \code
* for (auto&& func : classByType<MyClass>().functionIterator())
* for (auto&& func : classByType<MyClass>().functions())
* foo(func.name(), func.value());
* \endcode
*/
FunctionTable::Iterator functionIterator() const;
FunctionView functions() const;

/**
* \brief Look up a function by name and return success
Expand Down Expand Up @@ -303,11 +306,11 @@ class PONDER_API Class : public Type
* \return An iterator that can be used to iterator over all properties
*
* \code
* for (auto&& prop : ponder::classByType<MyClass>().propertyIterator())
* for (auto&& prop : ponder::classByType<MyClass>())
* foo(prop.name(), prop.value());
* \endcode
*/
PropertyTable::Iterator propertyIterator() const;
PropertyView properties() const;

/**
* \brief Look up a property by name and return success
Expand Down
8 changes: 4 additions & 4 deletions include/ponder/class.inl
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ inline void Class::undeclare()
detail::ClassManager::instance().removeClass(detail::getTypeId<T>());
}

inline Class::FunctionTable::Iterator Class::functionIterator() const
inline Class::FunctionView Class::functions() const
{
return m_functions.getIterator();
return FunctionView(m_functions.begin(), m_functions.end());
}

inline bool Class::tryFunction(const IdRef name, const Function *& funcRet) const
Expand All @@ -83,9 +83,9 @@ inline bool Class::tryFunction(const IdRef name, const Function *& funcRet) cons
return false;
}

inline Class::PropertyTable::Iterator Class::propertyIterator() const
inline Class::PropertyView Class::properties() const
{
return m_properties.getIterator();
return PropertyView(m_properties.begin(), m_properties.end());
}

inline bool Class::tryProperty(const IdRef name, const Property *& propRet) const
Expand Down
6 changes: 3 additions & 3 deletions include/ponder/classget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
#include <string>

namespace ponder {

/**
* \brief Get the total number of existing metaclasses
*
Expand All @@ -57,9 +57,9 @@ size_t classCount();
* \relates Class
* \snippet inspect.cpp classIterator
*
* \return Class iterator: `pair<String, Class*>`
* \return ClassView
*/
const detail::ClassManager& classIterator();
detail::ClassManager::ClassView classes();

/**
* \brief Get a metaclass from its name
Expand Down
4 changes: 2 additions & 2 deletions include/ponder/classget.inl
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ inline size_t classCount()
return detail::ClassManager::instance().count();
}

inline const detail::ClassManager& classIterator()
inline detail::ClassManager::ClassView classes()
{
return detail::ClassManager::instance();
return detail::ClassManager::instance().getClasses();
}

inline const Class& classByName(IdRef name)
Expand Down
22 changes: 4 additions & 18 deletions include/ponder/detail/classmanager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ class PONDER_API ClassManager : public ObserverNotifier

public:

typedef View<const Class&, ClassTable::const_iterator> ClassView;

/**
* \brief Get the unique instance of the class
*
Expand Down Expand Up @@ -97,24 +99,6 @@ class PONDER_API ClassManager : public ObserverNotifier
*/
size_t count() const;

/**
* \brief Begin iterator for iterating over contained classes
*
* \return An iterator
*
* \see classIterator()
*/
ClassTable::const_iterator begin() const;

/**
* \brief End iterator for iterating over contained classes
*
* \return An iterator
*
* \see classIterator()
*/
ClassTable::const_iterator end() const;

/**
* \brief Get a metaclass from a C++ type
*
Expand Down Expand Up @@ -182,6 +166,8 @@ class PONDER_API ClassManager : public ObserverNotifier
*/
~ClassManager();

ClassView getClasses() const;

private:

ClassTable m_classes; // Table storing classes indexed by their ID
Expand Down
15 changes: 2 additions & 13 deletions include/ponder/detail/dictionary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,8 @@ class Dictionary
typedef pair_t value_type;
typedef typename container_t::const_iterator const_iterator;

const_iterator begin() const { return m_contents.begin(); }
const_iterator end() const { return m_contents.end(); }

class Iterator {
const_iterator m_begin, m_end;
public:
Iterator(const_iterator b, const_iterator e) : m_begin(b), m_end(e) {}
const_iterator begin() const { return m_begin; }
const_iterator end() const { return m_end; }
};

// Allow iteration of dictionary without exposing the API.
Iterator getIterator() const { return Iterator(begin(), end()); }
const_iterator begin() const { return m_contents.cbegin(); }
const_iterator end() const { return m_contents.cend(); }

const_iterator findKey(KEY_REF key) const
{
Expand Down
50 changes: 50 additions & 0 deletions include/ponder/type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,56 @@ struct Parameter
//};

} // namespace policy

template <typename T, typename IT>
class ViewIterator
{
private:
IT m_iter;
class Holder
{
const T m_value;
public:
Holder(IT value) : m_value(value) {}
T operator*() { return m_value; }
};
public:
typedef T value_type;
typedef std::ptrdiff_t difference_type;
typedef std::input_iterator_tag iterator_category;

explicit ViewIterator(IT value) : m_iter(value) {}
value_type operator*() const { return *m_iter->second; }
bool operator==(const ViewIterator& other) const { return m_iter == other.m_iter; }
bool operator!=(const ViewIterator& other) const { return !(*this == other); }
Holder operator++(int)
{
Holder ret(m_iter);
++m_iter;
return ret;
}
ViewIterator& operator++()
{
++m_iter;
return *this;
}
};

template <typename T, typename IT>
class View
{
public:
typedef ViewIterator<T, IT> Iterator;

View(IT b, IT e) : m_begin(b), m_end(e) {}

Iterator begin() { return Iterator(m_begin); }
Iterator end() { return Iterator(m_end); }

private:
IT m_begin, m_end;
};

} // namespace ponder

#endif // PONDER_TYPE_HPP
9 changes: 2 additions & 7 deletions src/classmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,9 @@ size_t ClassManager::count() const
return m_classes.size();
}

ClassManager::ClassTable::const_iterator ClassManager::begin() const
ClassManager::ClassView ClassManager::getClasses() const
{
return m_classes.begin();
}

ClassManager::ClassTable::const_iterator ClassManager::end() const
{
return m_classes.end();
return ClassView(m_classes.begin(), m_classes.end());
}

const Class* ClassManager::getByIdSafe(TypeId const& id) const
Expand Down
7 changes: 3 additions & 4 deletions test/examples/userdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,10 @@ static void test()
std::cout << (help ? help->to<ponder::Id>() : "no help") << std::endl;

// print functions and any help
for (auto const& it : cls.functionIterator())
for (auto const& fn : cls.functions())
{
auto const& fn = it.second;
std::cout << "\t" << fn->name() << ": ";
help = ponder::userDataStore()->getValue(*fn, "help");
std::cout << "\t" << fn.name() << ": ";
help = ponder::userDataStore()->getValue(fn, "help");
if (help)
std::cout << (help ? help->to<ponder::Id>() : "no help") << std::endl;
}
Expand Down
8 changes: 4 additions & 4 deletions test/ponder/class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,9 @@ TEST_CASE("Class metadata can be retrieved")
SECTION("iteration")
{
size_t count = 0;
for (auto&& cls : ponder::classIterator())
for (const auto& cls : ponder::classes())
{
(void) cls.second->name();
(void) cls.name();
++count;
}
REQUIRE(count == ponder::classCount());
Expand Down Expand Up @@ -362,7 +362,7 @@ TEST_CASE("Class members can be inspected")
SECTION("can iterate over properties")
{
int index = 0;
for (auto&& prop : metaclass.propertyIterator())
for (const auto& prop : metaclass.properties())
{
switch (index++) {
case 0:
Expand All @@ -377,7 +377,7 @@ TEST_CASE("Class members can be inspected")
SECTION("can iterate over functions")
{
int index = 0;
for (auto&& func : metaclass.functionIterator())
for (auto&& func : metaclass.functions())
{
switch (index++) {
case 0:
Expand Down
2 changes: 1 addition & 1 deletion test/ponder/dictionary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ TEST_CASE("Ponder has a dictionary")
SECTION("can iterate over key,values")
{
int count = 0;
for (auto&& it : dict->getIterator())
for (const auto& it : *dict)
{
REQUIRE(dict->at(count)->name() == it.name());
REQUIRE(dict->at(count)->value() == it.value());
Expand Down
3 changes: 1 addition & 2 deletions test/ponder/userobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,12 +464,11 @@ TEST_CASE("User objects can be inspected and modified")
ponder::UserObject userObject(&object);

int index = 0;
for (auto&& prop : ponder::classByType<MyClass>().propertyIterator())
for (const auto& prop : ponder::classByType<MyClass>().properties())
{
switch (index) {
case 0:
REQUIRE(prop.name() == ponder::String("p"));
REQUIRE(prop.value()->name() == ponder::String("p"));
break;
default: ;
}
Expand Down

0 comments on commit 065121e

Please sign in to comment.