Skip to content

Commit b0ae81b

Browse files
committed
fable: Add extra type traits for working with schema types
1 parent a868f9a commit b0ae81b

File tree

1 file changed

+45
-5
lines changed

1 file changed

+45
-5
lines changed

fable/include/fable/schema/interface.hpp

+45-5
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@
2525
#ifndef FABLE_SCHEMA_INTERFACE_HPP_
2626
#define FABLE_SCHEMA_INTERFACE_HPP_
2727

28-
#include <memory> // for shared_ptr<>
29-
#include <string> // for string
30-
#include <utility> // for move
28+
#include <memory> // for shared_ptr<>
29+
#include <string> // for string
30+
#include <type_traits> // for enable_if_t<>, is_base_of<>
31+
#include <utility> // for move
3132

3233
#include <fable/conf.hpp> // for Conf
3334
#include <fable/error.hpp> // for SchemaError
@@ -234,10 +235,21 @@ class Interface {
234235
virtual void reset_ptr() = 0;
235236
};
236237

238+
/**
239+
* Use SFINAE mechanism to disable a template function when S is not a subclass
240+
* of Interface, hence not a schema.
241+
*
242+
* \example
243+
* template<typename S, typename = enable_if_schema_t<S>>
244+
* void foobar(S schema);
245+
*/
246+
template <typename S>
247+
using enable_if_schema_t = std::enable_if_t<std::is_base_of<Interface, S>::value>;
248+
237249
// ------------------------------------------------------------------------- //
238250

239251
class Box : public Interface {
240-
public:
252+
public: // Constructors
241253
Box() = default;
242254
Box(const Box&) = default;
243255
Box(Box&&) = default;
@@ -246,7 +258,13 @@ class Box : public Interface {
246258
Box(Interface* i) : impl_(i) { assert(impl_); } // NOLINT
247259
Box(std::shared_ptr<Interface> i) : impl_(std::move(i)) { assert(impl_); } // NOLINT
248260

249-
public:
261+
public: // Special
262+
template <typename T>
263+
std::shared_ptr<const T> as() const {
264+
return std::dynamic_pointer_cast<T>(impl_);
265+
}
266+
267+
public: // Overrides
250268
Interface* clone() const override { return impl_->clone(); }
251269
JsonType type() const override { return impl_->type(); }
252270
std::string type_string() const override { return impl_->type_string(); }
@@ -355,6 +373,28 @@ class Base : public Interface {
355373

356374
// ------------------------------------------------------------------------- //
357375

376+
/**
377+
* Use SFINAE mechanism to disable a template function when S is not a subclass
378+
* of Confable.
379+
*
380+
* \example
381+
* template<typename T, typename = enable_if_confable_t<T>>
382+
* void foobar(T x);
383+
*/
384+
template <typename T>
385+
using enable_if_confable_t = std::enable_if_t<std::is_base_of<Confable, T>::value>;
386+
387+
/**
388+
* Use SFINAE mechanism to disable a template function when S is a subclass
389+
* of Confable.
390+
*
391+
* \example
392+
* template<typename T, typename = enable_if_not_confable_t<T>>
393+
* void foobar(T x);
394+
*/
395+
template <typename T>
396+
using enable_if_not_confable_t = std::enable_if_t<!std::is_base_of<Confable, T>::value>;
397+
358398
template <typename T, std::enable_if_t<std::is_base_of<Confable, T>::value, int> = 0>
359399
auto make_prototype(std::string&& desc = "");
360400

0 commit comments

Comments
 (0)