Savarese Software Research Corporation
BindProperties.h
Go to the documentation of this file.
00001 /* Copyright 2006-2009 Savarese Software Research Corporation
00002  *
00003  * Licensed under the Apache License, Version 2.0 (the "License");
00004  * you may not use this file except in compliance with the License.
00005  * You may obtain a copy of the License at
00006  *
00007  *     https://www.savarese.com/software/ApacheLicense-2.0
00008  *
00009  * Unless required by applicable law or agreed to in writing, software
00010  * distributed under the License is distributed on an "AS IS" BASIS,
00011  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012  * See the License for the specific language governing permissions and
00013  * limitations under the License.
00014  */
00015 
00021 #ifndef __SSRC_WSPR_UTILITY_BIND_PROPERTIES_H
00022 #define __SSRC_WSPR_UTILITY_BIND_PROPERTIES_H
00023 
00024 #include <ssrc/wisp/utility/wisp_struct.h>
00025 #include <ssrc/wispers/utility/Properties.h>
00026 #include <type_traits>
00027 
00028 __BEGIN_NS_SSRC_WSPR_UTILITY
00029 
00030 // TODO: find a cleaner way to do this.
00031 template<typename T>
00032 struct is_bindable {
00033   typedef ssrc::wisp::utility::wisp_struct type;
00034 };
00035 
00036 #define WSPR_IS_BINDABLE_SEQUENCE(T)            \
00037   __BEGIN_NS_SSRC_WSPR_UTILITY                  \
00038   template<> struct is_bindable<T> {            \
00039   typedef property_vector type;                 \
00040   };                                            \
00041   __END_NS_SSRC_WSPR_UTILITY
00042 
00043 #define WSPR_IS_PRIMITIVE_BINDABLE_SEQUENCE(T)  \
00044   __BEGIN_NS_SSRC_WSPR_UTILITY                  \
00045   template<> struct is_bindable<T> {            \
00046   typedef primitive_property_vector type;       \
00047   };                                            \
00048   __END_NS_SSRC_WSPR_UTILITY
00049 
00069 class BindProperties {
00070   Properties & properties;
00071 
00072   template<typename V>
00073   const BindProperties &
00074   bind(const char * const key, const V & value,
00075        const std::false_type&, const ssrc::wisp::utility::wisp_struct&) const
00076   {
00077     properties.set(value, key);
00078     return *this;
00079   }
00080 
00081   template<typename V>
00082   const BindProperties &
00083   bind(const char * const key, const V & value,
00084        const std::true_type&, const ssrc::wisp::utility::wisp_struct&) const
00085   {
00086     value.visit(BindProperties(*properties.create_node(key)));
00087     return *this;
00088   }
00089 
00090   // Support functions for bindable sequence bind.
00091   template<typename Iterator>
00092   static void visit(Iterator & v, Properties & p,
00093                     const ssrc::wisp::utility::wisp_struct&)
00094   {
00095     v->visit(BindProperties(p));
00096   }
00097 
00098   template<typename Iterator>
00099   static void visit(Iterator & v, Properties & p,
00100                     const primitive_property_vector&)
00101   {
00102     primitive_property_vector & pv = p.create_primitive_property_vector();
00103 
00104     for(typename Iterator::value_type::const_iterator it = v->begin(),
00105           && end = v->end(); it != end; ++it)
00106     {
00107       pv.push_back(*it);
00108     }
00109   }
00110 
00111   template<typename Iterator>
00112   static void visit(Iterator & v, Properties & p, const property_vector&)
00113   {
00114     property_vector & pv = p.create_property_vector();
00115 
00116     for(typename Iterator::value_type::const_iterator it = v->begin(),
00117           && end = v->end(); it != end; ++it)
00118     {
00119       pv.push_back(new Properties);
00120       visit(it, pv.back(), typename is_bindable<typename Iterator::value_type::value_type>::type());
00121     }
00122   }
00123 
00124   // For bindable sequences.
00125   template<typename V>
00126   const BindProperties &
00127   bind(const char * const key, const V & value,
00128        const std::false_type&, const primitive_property_vector&) const
00129   {
00130     primitive_property_vector & pv =
00131       properties.create_primitive_property_vector(key);
00132 
00133     for(typename V::const_iterator it = value.begin(), && end = value.end();
00134         it != end; ++it)
00135     {
00136       pv.push_back(*it);
00137     }
00138 
00139     return *this;
00140   }
00141 
00142   template<typename V>
00143   const BindProperties &
00144   bind(const char * const key, const V & value,
00145        const std::false_type&, const property_vector&) const
00146   {
00147     property_vector & pv = properties.create_property_vector(key);
00148 
00149     for(typename V::const_iterator it = value.begin(), && end = value.end();
00150         it != end; ++it)
00151     {
00152       pv.push_back(new Properties);
00153       visit(it, pv.back(),
00154             typename is_bindable<typename V::value_type>::type());
00155     }
00156 
00157     return *this;
00158   }
00159 
00160 public:
00161 
00169   explicit BindProperties(Properties & properties) : properties(properties) { }
00170 
00177   template<typename V>
00178   const BindProperties &
00179   operator()(const char * const key, const V & value) const {
00180     return bind(key, value,
00181                 typename std::is_base_of<ssrc::wisp::utility::wisp_struct, V>::type(),
00182                 typename is_bindable<V>::type());
00183   }
00184 };
00185 
00186 __END_NS_SSRC_WSPR_UTILITY
00187 
00188 #endif

Savarese Software Research Corporation
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.