/** \file * Common utility classes wrappers. */ /* * Copyright © 2000, 2001 Sofus Mortensen * * This material is provided "as is", with absolutely no warranty * expressed or implied. Any use is at your own risk. Permission to * use or copy this software for any purpose is hereby granted without * fee, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is * granted, provided the above notices are retained, and a notice that * the code was modified is included with the above copyright notice. * * This header is part of Comet version 2. * https://github.com/alamaison/comet */ #ifndef COMET_COMMON_H #define COMET_COMMON_H #include <comet/config.h> #include <comet/interface.h> #include <wtypes.h> namespace comet { class uuid_t; template<typename Itf>class com_ptr; namespace impl { template<typename T> T* bad_alloc_check(T* x) { if (!x) throw std::bad_alloc(); return x; } /** Implementation struct for auto_attach. * \internal */ template<typename T> class auto_attach_t { public: explicit auto_attach_t(const T& v) : val_(v) {}; const T& get() const { return val_; } private: const T& val_; auto_attach_t& operator=(const auto_attach_t&); }; // Forward declare all these - only used if we actually WANT a // safearray. /** Safearray traits for the given type. * \internal */ template<typename T> struct sa_traits; /** Safearray iterator for the given type. * \internal */ template<typename S,typename T> class sa_iterator; /** Safearray const traits for the given type. * \internal */ template<typename T> struct const_traits; /** Safearray non-const traits for the given type. * \internal */ template<typename T> struct nonconst_traits; enum sa_traits_check_type { stct_features_ok, stct_vt_ok, stct_iid_ok }; enum sa_traits_extras_type { stet_null, stet_record, stet_iid }; // Interface traits are needed by all interfaces so that we can create // safearrays of the types. template<typename INTERFACE, VARTYPE VT, long FEATURE_FLAG> struct interface_sa_traits { enum { vt = VT }; enum { check_type = stct_iid_ok }; enum { extras_type = stet_iid }; typedef INTERFACE* raw; typedef com_ptr<INTERFACE> value_type; typedef com_ptr<INTERFACE> & reference; typedef const com_ptr<INTERFACE> & const_reference; static reference create_reference(raw& x) { return *reinterpret_cast<com_ptr< INTERFACE>*>(&x); } static const_reference create_const_reference(raw& x) { return *reinterpret_cast<const com_ptr< INTERFACE >*>(&x); } typedef nonconst_traits<com_ptr<INTERFACE> > nct; typedef sa_iterator<com_ptr<INTERFACE>, nct > iterator; typedef sa_iterator<com_ptr<INTERFACE>, const_traits<com_ptr<INTERFACE> > > const_iterator; static bool are_features_ok(unsigned short f) { return (f & FEATURE_FLAG) != 0 && (f & FADF_HAVEIID) != 0; } static const uuid_t& iid() { return uuidof<INTERFACE>(); } }; /** Basic safearray traits - used by enums. * \internal */ template<typename T, VARTYPE VT> struct basic_sa_traits { enum { vt = VT }; enum { check_type = stct_vt_ok }; enum { extras_type = stet_null }; typedef T raw; typedef T value_type; typedef T& reference; typedef const T& const_reference; static reference create_reference(T& x) { return x; } static const_reference create_const_reference(T& x) { return x; } typedef T* iterator; typedef const T* const_iterator; static bool are_features_ok(unsigned short) { return true; } }; } /*! \addtogroup COMType */ //@{ /// Used to attach a raw parameter to a wrapper. template<typename T> impl::auto_attach_t<T> auto_attach(const T& t) { return impl::auto_attach_t<T>(t); } // template<typename T, typename U> inline T up_cast(const U& u, T* = 0) { return u; } /*! VARIANT_BOOL to bool [in] converter. * This is used by the generated wrappers. */ inline VARIANT_BOOL bool_in(bool x) { return x ? COMET_VARIANT_TRUE : COMET_VARIANT_FALSE; } /** \class bool_out common.h comet/common.h * VARIANT_BOOL to bool [out] converter. * This is used by the generated wrappers. */ class bool_out { public: operator VARIANT_BOOL*() { return &vb_; } bool_out(bool& b) : b_(b) {} ~bool_out() { b_ = vb_ ? true : false; } private: bool_out &operator=( const bool_out &); VARIANT_BOOL vb_; bool& b_; }; namespace impl { class bool_adapter_t { public: bool_adapter_t(VARIANT_BOOL* p) : pb_(p) { b_ = *pb_ ? true : false; } ~bool_adapter_t() { *pb_ = b_ ? COMET_VARIANT_TRUE : COMET_VARIANT_FALSE; } bool& ref() { return b_; } private: bool_adapter_t(const bool_adapter_t&); bool_adapter_t& operator=(const bool_adapter_t&); VARIANT_BOOL* pb_; bool b_; }; } /** \class bool_inout common.h comet/common.h * VARIANT_BOOL to bool [in,out] converter. * This is used by the generated wrappers. */ class bool_inout { public: operator VARIANT_BOOL*() { return &vb_; } bool_inout(bool& b) : b_(b), vb_(b ? COMET_VARIANT_TRUE : COMET_VARIANT_FALSE) {} ~bool_inout() { b_ = vb_ ? true : false; } private: bool_inout &operator=(const bool_inout &); VARIANT_BOOL vb_; bool& b_; }; /** \class variant_bool_t common.h comet/common.h * VARIANT_BOOL wrapper for structs. * Stands in place of a VARIANT_BOOL in a struct, and behaves like a bool. * This is imporant as sizeof(VARIANT_BOOL) != sizeof(bool). */ class variant_bool_t { VARIANT_BOOL vb_; public: /// \name Constructors. //@{ variant_bool_t(): vb_(COMET_VARIANT_FALSE) {} variant_bool_t(const impl::auto_attach_t<VARIANT_BOOL> &b) : vb_(b.get()) {} variant_bool_t(bool b) : vb_(b?COMET_VARIANT_TRUE:COMET_VARIANT_FALSE) {} //@} /// \name Assignment operators. //@{ variant_bool_t &operator=( bool b) { vb_ = b?COMET_VARIANT_TRUE:COMET_VARIANT_FALSE; return *this;} variant_bool_t &operator=( const impl::auto_attach_t<VARIANT_BOOL> &b) { vb_ = b.get(); return *this; } //@} /// \name Boolean operators. //@{ operator bool() const{ return vb_!= COMET_VARIANT_FALSE; } bool operator !() const { return vb_== COMET_VARIANT_FALSE; } bool operator==( variant_bool_t vb) const { return vb.vb_ == vb_; } bool operator!=( variant_bool_t vb) const { return vb.vb_ != vb_; } //@} /// \name Bitwise operators //@{ variant_bool_t operator~() const { variant_bool_t temp(*this); temp.vb_ = (VARIANT_BOOL)~(temp.vb_); return temp; } variant_bool_t &operator&=( const variant_bool_t &b) { vb_ &= b.vb_; return *this; } variant_bool_t &operator|=( const variant_bool_t &b) { vb_ |= b.vb_; return *this; } variant_bool_t &operator^=( const variant_bool_t &b) { vb_ ^= b.vb_; return *this; } variant_bool_t operator&( const variant_bool_t &b)const { variant_bool_t temp(*this); temp.vb_ &= b.vb_; return temp; } variant_bool_t operator|( const variant_bool_t &b)const { variant_bool_t temp(*this); temp.vb_ |= b.vb_; return temp; } variant_bool_t operator^( const variant_bool_t &b)const { variant_bool_t temp(*this); temp.vb_ ^= b.vb_; return temp; } //@} /// \name bool operators //@{ bool operator&( bool b)const { return b & operator bool(); } bool operator|( bool b)const { return b | operator bool(); } bool operator^( bool b)const { return b ^ operator bool(); } //@} static const variant_bool_t &create_const_reference(const VARIANT_BOOL &vb) { return reinterpret_cast<const variant_bool_t &>(vb); } static variant_bool_t &create_reference(VARIANT_BOOL &vb) { return reinterpret_cast<variant_bool_t &>(vb); } ///\name Raw accessors //@{ VARIANT_BOOL in() { return vb_; } VARIANT_BOOL *out() { return &vb_; } VARIANT_BOOL *inout() { return &vb_; } //@} /** Allow treating of class as a bool *. * \sa bool_ptr() */ class bool_pointer_t { friend class variant_bool_t; protected: bool_pointer_t( VARIANT_BOOL &vb) : vb_(vb), b_( vb != COMET_VARIANT_FALSE) {} public: ~bool_pointer_t() { vb_ = b_ ? COMET_VARIANT_TRUE: COMET_VARIANT_FALSE; } operator bool*(){ return &b_; } operator const bool*()const{ return &b_; } private: bool_pointer_t &operator=(const bool_pointer_t &); bool b_; VARIANT_BOOL &vb_; }; /** Return a class that stands in for a bool *. Should be used in place of operator & for passing in to a bool * function. \code variant_bool_t vb; SomeFunc(vb.bool_ptr()); \endcode */ bool_pointer_t bool_ptr() { return bool_pointer_t(vb_); } const bool_pointer_t bool_ptr() const { return bool_pointer_t(const_cast<VARIANT_BOOL &>(vb_)); } friend class bool_reference_t; /** Allow efficient choosing between a bool& and a variant_bool&. */ class bool_reference_chooser_t { friend class variant_bool_t; variant_bool_t &vbt_; protected: bool_reference_chooser_t(variant_bool_t &vbt):vbt_(vbt) {} private: bool_reference_chooser_t &operator=(const bool_reference_chooser_t &); public: inline operator variant_bool_t&() { return vbt_;} inline operator const variant_bool_t&()const { return vbt_;} }; /** Allow treating of a class as a bool &. * \sa bool_ref() */ class bool_reference_t : protected bool_pointer_t { public: bool_reference_t( bool_reference_chooser_t &brc ) : bool_pointer_t(*static_cast<variant_bool_t&>(brc).inout()) {} operator bool &(){ return tmp; /*return * (bool_pointer_t::operator bool*());*/ } operator const bool &()const { return *(bool_pointer_t::operator const bool*()); } bool tmp; }; /** Return a class that stands in for a bool & or a variant_bool_t &. */ bool_reference_chooser_t bool_ref() { return bool_reference_chooser_t(*this); } const bool_reference_chooser_t bool_ref() const { return bool_reference_chooser_t(const_cast<variant_bool_t &>(*this)); } }; //@} } // namespace #endif