#include "conversion_detection.h" ////////////////////////////////////////////////////////////////////// // For custom error messages ////////////////////////////////////////////////////////////////////// template struct Error {}; ////////////////////////////////////////////////////////////////////// // BoolError doesn't exist; used to create errors from booleans ////////////////////////////////////////////////////////////////////// template struct BoolError; template <> struct BoolError {}; ////////////////////////////////////////////////////////////////////// // Usual meta-IF ////////////////////////////////////////////////////////////////////// template struct IF; template struct IF { typedef T RET; }; template struct IF { typedef E RET; }; ////////////////////////////////////////////////////////////////////// // A way to thunk an int; not useful by itself, but useful to make "then" // and "else" clauses of IF parallel ////////////////////////////////////////////////////////////////////// template struct IntHolderThunk { template struct Value { static const int RET = N; }; }; ////////////////////////////////////////////////////////////////////// // This class helps us instantiate a template method during the act of // accessing a compile-time constant value ////////////////////////////////////////////////////////////////////// template struct Blah { static const int x = 1; }; ////////////////////////////////////////////////////////////////////// // This just makes it easier to instantiate the check_structural() // function of a static interface ////////////////////////////////////////////////////////////////////// template void check_structural() { (void) ((void (I::*)(T)) &I::template check_structural); } ////////////////////////////////////////////////////////////////////// // StaticIsA ////////////////////////////////////////////////////////////////////// template struct StaticIsA { // Note to self: need to bootstrap this, as there's a constraint! :) static const bool builtin_isa = Base::template Traits::valid; static const bool named_isa = Inherits::value; struct Thunk { template struct Value { static const int RET = Blah<&check_structural >::x; }; }; typedef typename IF >::RET Compute; // "valid" is true if the relationship holds; will also diagnose // structural conformance problems if any static const bool valid = Compute::template Value::RET; }; ////////////////////////////////////////////////////////////////////// // Named ////////////////////////////////////////////////////////////////////// template struct Named { static const bool valid = Inherits::value; }; ////////////////////////////////////////////////////////////////////// // RequireStructural ////////////////////////////////////////////////////////////////////// template inline void RequireStructural() { (void) ((void (*)()) &check_structural); } ////////////////////////////////////////////////////////////////////// // RequireNamed ////////////////////////////////////////////////////////////////////// template inline void RequireNamed() { BoolError< Named::valid > RequireNamed_has_failed; (void) RequireNamed_has_failed; } ////////////////////////////////////////////////////////////////////// // RequireBoth ////////////////////////////////////////////////////////////////////// template inline void RequireBoth() { RequireNamed(); RequireStructural(); } ////////////////////////////////////////////////////////////////////// // This stuff is just to help users define static interfaces easily ////////////////////////////////////////////////////////////////////// #define MAKE_TRAITS \ template \ struct Traits { \ static const bool valid = false; \ }; struct Valid { static const bool valid = true; protected: ~Valid() {}; }; template struct HeroicProxy { HeroicProxy( const T& ) {} };