Guest User

property.hpp

a guest
Oct 9th, 2012
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.93 KB | None | 0 0
  1. // property.hpp
  2.  
  3. // Easy GUI Library
  4. //
  5. // Copyright (C) 2008 John Torjo (see http://torjo.com/contact/ for email)
  6. //
  7. // Permission to copy, use, sell and distribute this software is granted
  8. // provided this copyright notice appears in all copies.
  9. // Permission to modify the code and to distribute modified code is granted
  10. // provided this copyright notice appears in all copies, and a notice
  11. // that the code was modified is included with the copyright notice.
  12. //
  13. // This software is provided "as is" without express or implied warranty,
  14. // and with no claim as to its suitability for any purpose.
  15. //
  16. // You can find the latest version of this library at http://www.torjo.com/egui/
  17.  
  18.  
  19. #ifndef JT07022008_property_HPP_DEFINED
  20. #define JT07022008_property_HPP_DEFINED
  21.  
  22. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  23. # pragma once
  24. #endif
  25.  
  26.  
  27. #include "egui/core/detail/fwd.hpp"
  28.  
  29. namespace egui {
  30.  
  31. struct os {
  32.   typedef enum type {
  33.     win_2k          = 0,
  34.     win_2k_sp4      = 1000,
  35.     win_xp          = 2000,
  36.     win_xp_sp2      = 3000,
  37.     win_vista       = 4000
  38.   };
  39. };
  40.  
  41. #ifndef EGUI_OS
  42. // os::win_xp_sp2
  43. #define EGUI_OS 3000
  44. #endif
  45.  
  46. struct property_access {
  47.     typedef enum type {
  48.         r = 1,  // read
  49.         w = 2,  // write
  50.         rw = 3  // read-write
  51.     };
  52. };
  53.  
  54. namespace property_base {
  55.     template<class type> struct property_write ;
  56. }
  57.  
  58. namespace property_operators {
  59.     template<class self_type, class property_type> struct string {
  60.         // +=
  61.         property_type operator+=(const property_type & val) {
  62.             self_type & self = static_cast<self_type&>(*this);
  63.             property_type new_val = self.get() + val;
  64.             self.set( new_val);
  65.             return new_val;
  66.         }
  67.     };
  68.  
  69.     template<class self_type, class property_type> struct flag {
  70.         // |=, &=
  71.         property_type operator|=(const property_type & val) {
  72.             self_type & self = static_cast<self_type&>(*this);
  73.             property_type new_val = self.get() | val;
  74.             self.set( new_val);
  75.             return new_val;
  76.         }
  77.         property_type operator&=(const property_type & val) {
  78.             self_type & self = static_cast<self_type&>(*this);
  79.             property_type new_val = self.get() & val;
  80.             self.set( new_val);
  81.             return new_val;
  82.         }
  83.     };
  84.  
  85.     template<class self_type, class property_type> struct number {
  86.         // +=, -=, *=, /=
  87.         // ++, --
  88.  
  89.         property_type operator+=(const property_type & val) {
  90.             self_type & self = static_cast<self_type&>(*this);
  91.             property_type new_val = self.get() + val;
  92.             self.set( new_val);
  93.             return new_val;
  94.         }
  95.         property_type operator-=(const property_type & val) {
  96.             self_type & self = static_cast<self_type&>(*this);
  97.             property_type new_val = self.get() - val;
  98.             self.set( new_val);
  99.             return new_val;
  100.         }
  101.         property_type operator*=(const property_type & val) {
  102.             self_type & self = static_cast<self_type&>(*this);
  103.             property_type new_val = self.get() * val;
  104.             self.set( new_val);
  105.             return new_val;
  106.         }
  107.         property_type operator/=(const property_type & val) {
  108.             self_type & self = static_cast<self_type&>(*this);
  109.             property_type new_val = self.get() / val;
  110.             self.set( new_val);
  111.             return new_val;
  112.         }
  113.  
  114.         self_type & operator++() {
  115.             self_type & self = static_cast<self_type&>(*this);
  116.             property_type new_val = self.get() + 1;
  117.             self.set( new_val);
  118.             return self;
  119.         }
  120.         property_type operator++(int) {
  121.             self_type & self = static_cast<self_type&>(*this);
  122.             property_type old_val = self.get() ;
  123.             self.set( old_val + 1);
  124.             return old_val;
  125.         }
  126.  
  127.         self_type & operator--() {
  128.             self_type & self = static_cast<self_type&>(*this);
  129.             property_type new_val = self.get() - 1;
  130.             self.set( new_val);
  131.             return self;
  132.         }
  133.         property_type operator--(int) {
  134.             self_type & self = static_cast<self_type&>(*this);
  135.             property_type old_val = self.get() ;
  136.             self.set( old_val - 1);
  137.             return old_val;
  138.         }
  139.  
  140.         // FIXME perhaps in the future I will allow only | and & for flags
  141.         // |=, &=h
  142.         property_type operator|=(const property_type & val) {
  143.             self_type & self = static_cast<self_type&>(*this);
  144.             property_type new_val = self.get() | val;
  145.             self.set( new_val);
  146.             return new_val;
  147.         }
  148.         property_type operator&=(const property_type & val) {
  149.             self_type & self = static_cast<self_type&>(*this);
  150.             property_type new_val = self.get() & val;
  151.             self.set( new_val);
  152.             return new_val;
  153.         }
  154.     };
  155.  
  156.     template<class type, class self_type> struct operator_base {};
  157.     template<class self_type> struct operator_base<types::int64,self_type>
  158.         : number < self_type, types::int64 > {};
  159.     template<class self_type> struct operator_base<int,self_type>
  160.         : number < self_type, int > {};
  161.     template<class self_type> struct operator_base<egui::string,self_type>
  162.         : string< self_type, egui::string > {};
  163. }
  164.  
  165. namespace property_base {
  166.  
  167.     template<class type> struct getter_ptr {
  168.         getter_ptr(const type & val) : val(val) {}
  169.  
  170.         const type *operator->() const { return &val; }
  171.     private:
  172.         type val;
  173.     };
  174.  
  175.     template<class type> struct property_read ;
  176.     template<class type> inline void do_set_getter(property_read<type> & val, boost::function0<type> f ) ;
  177.  
  178.     template<class type>
  179.     struct property_read {
  180.         operator type() const { return get(); }
  181.         type get() const { return getter(); }
  182.  
  183.         // just in case you want to call a const method on the result
  184.         getter_ptr<type> operator->() const { return getter(); }
  185.     private:
  186.         template<class other_type> friend inline void do_set_getter(property_read<other_type> &, boost::function0<other_type> f );
  187.         boost::function0< type  > getter;
  188.     };
  189.     template<class type> inline void do_set_getter(property_read<type> & val, boost::function0<type> f ) {
  190.         val.getter = f;
  191.     }
  192.  
  193.  
  194.  
  195.     template<class type> struct property_write ;
  196.     template<class type> inline void do_set_setter(property_write<type> & val, boost::function1<void, const type&> f ) ;
  197.  
  198.     // here, care about operators!
  199.     template<class type>
  200.     struct property_write {
  201.         void set(const type& val) {
  202.             setter(val);
  203.         }
  204.         void operator=(const type & val) {
  205.             setter(val);
  206.             return val;
  207.         }
  208.     private:
  209.         template<class other_type>
  210.         friend inline void do_set_setter(property_write<other_type> & val,
  211.                                         boost::function1<void, const other_type&> f ) ;
  212.  
  213.         boost::function1< void, const type& > setter;
  214.     };
  215.     template<class type> inline void do_set_setter(property_write<type> & val, boost::function1<void, const type&> f ) {
  216.         val.setter = f;
  217.     }
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.     template<class type, class param, int have_read, int have_write> struct property_one_arg ;
  225.  
  226.     template<class type, class param, int have_read, int have_write> struct property_one_arg_holder {
  227.         typedef property_one_arg<type,param,have_read,have_write> property_type;
  228.         property_one_arg_holder(property_type * self, const param& arg) : self(self), arg(arg) {}
  229.  
  230.         operator type() const {
  231.             // FIXME - see if this affects compile time
  232.             // BOOST_STATIC_ASSERT(have_read);
  233.             return self->getter(arg);
  234.         }
  235.  
  236.         const type& operator=(const type & val) {
  237.             // FIXME - see if this affects compile time
  238.             // BOOST_STATIC_ASSERT(have_write);
  239.             self->setter(arg, val);
  240.             return val;
  241.         }
  242.     private:
  243.         property_type* self;
  244.         param arg;
  245.     };
  246.  
  247.    
  248.     template<class type, class param, int have_read, int have_write> struct property_one_arg;
  249. //    template<class type, class param, int have_read, int have_write> inline void do_set_getter(
  250.   //      property_one_arg<type,param,have_read,have_write> & val, boost::function1<type,param> f ) ;
  251. //    template<class type, class param, int have_read, int have_write, class p5, class p6> inline void do_set_setter(
  252.   //      property_one_arg<type,param,have_read,have_write> & val, boost::function2<void,p5,p6 > f ) ;
  253.  
  254.     template<class type, class param, int have_read, int have_write> struct property_one_arg {
  255.         typedef type value_type;
  256.         const property_one_arg_holder<type,param,have_read,have_write> operator()(const param & arg) const {
  257.             return property_one_arg_holder<type,param,have_read,have_write>( const_cast<property_one_arg*>(this) ,arg);
  258.         }
  259.         property_one_arg_holder<type,param,have_read,have_write> operator()(const param & arg) {
  260.             return property_one_arg_holder<type,param,have_read,have_write>(this,arg);
  261.         }
  262.     private:
  263. //        template<class p1,class p2, int p3, int p4> friend inline void do_set_getter(
  264.   //          property_one_arg<p1,p2,p3,p4> & val, boost::function1<p1,p2> f ) ;
  265.        
  266. //        template<class p1,class p2, int p3, int p4, class p5, class p6> friend inline void do_set_setter(
  267.   //          property_one_arg<p1,p2,p3,p4> & val, boost::function2<void,p5,p6 > f ) ;
  268.     public:
  269.         boost::function1< type , param > getter;
  270.         boost::function2< void, const param&, const type& > setter;
  271.     };
  272.  
  273.     template<class type, class param, int have_read, int have_write> inline void do_set_getter(
  274.             property_one_arg<type,param,have_read,have_write> & val, boost::function1<type,param> f ) {
  275.         val.getter = f;
  276.     }
  277.     template<class type, class param, int have_read, int have_write,class p5, class p6> inline void do_set_setter(
  278.             property_one_arg<type,param,have_read,have_write> & val, boost::function2<void,p5,p6 > f ) {
  279.         val.setter = f;
  280.     }
  281.  
  282.  
  283.  
  284.  
  285.  
  286.     template<os::type property_os, class base> struct only_for_os {};
  287.  
  288. #if EGUI_OS >= 4000
  289.     template<class base> struct only_for_os<os::win_vista, base> : base {};
  290. #endif
  291.  
  292. #if EGUI_OS >= 3000
  293.     template<class base> struct only_for_os<os::win_xp_sp2, base> : base {};
  294. #endif
  295.  
  296. #if EGUI_OS >= 2000
  297.     template<class base> struct only_for_os<os::win_xp, base> : base {};
  298. #endif
  299.  
  300. #if EGUI_OS >= 1000
  301.     template<class base> struct only_for_os<os::win_2k_sp4, base> : base {};
  302. #endif
  303.  
  304. #if EGUI_OS >= 0
  305.     template<class base> struct only_for_os<os::win_2k, base> : base {};
  306. #endif
  307.  
  308.  
  309. }
  310.  
  311.  
  312. /**
  313.     represents a window property - no arguments passed to the property
  314. */
  315. struct property
  316. {
  317.     template<class type, class base_type = void_, os::type property_os = os::win_2k >
  318.     struct rw
  319.         // we derive from base_type first, so that code-completion works (it's easy for the compiler to parse the base_type class)
  320.         : base_type
  321.         , property_base::only_for_os< property_os, property_base::property_read<type> >
  322.         , property_base::only_for_os< property_os, property_base::property_write<type> >
  323.         , property_operators::operator_base< type, rw<type,base_type,property_os> >
  324.     {
  325.         const type & operator=(const type & val) {
  326.             property_base::property_write<type>::set(val);
  327.             return val;
  328.         }
  329.     };
  330.  
  331.     template<class type, class base_type = void_, os::type property_os = os::win_2k >
  332.     struct r
  333.         : base_type
  334.         , property_base::only_for_os< property_os, property_base::property_read<type> >
  335.     {};
  336.  
  337.     template<class type, class base_type = void_, os::type property_os = os::win_2k >
  338.     struct w
  339.         : base_type
  340.         , property_base::only_for_os< property_os, property_base::property_write<type> >
  341.     {
  342.         const type & operator=(const type & val) {
  343.             property_base::property_write<type>::set(val);
  344.             return val;
  345.         }
  346.     };
  347. };
  348.  
  349. /**
  350.     represents a window property - no arguments passed to the property
  351. */
  352. struct property_one_arg
  353. {
  354.     template<class type, class param, class base_type = void_, os::type property_os = os::win_2k > struct rw
  355.         : base_type
  356.         , property_base::only_for_os< property_os, property_base::property_one_arg<type, param, 1, 1> >
  357.     {};
  358.  
  359.     template<class type, class param, class base_type = void_, os::type property_os = os::win_2k > struct r
  360.         : base_type
  361.         , property_base::only_for_os< property_os, property_base::property_one_arg<type, param, 1, 0> >
  362.     {};
  363.  
  364.     template<class type, class param, class base_type = void_, os::type property_os = os::win_2k > struct w
  365.         : base_type
  366.         , property_base::only_for_os< property_os, property_base::property_one_arg<type, param, 0, 1> >
  367.     {};
  368. };
  369.  
  370. }
  371.  
  372. #endif
Advertisement
Add Comment
Please, Sign In to add comment