Web Wispers 1.2.2 C++ Unit Test Coverage
Current view: top level - ssrc/wispers/utility - BindProperties.h (source / functions) Hit Total Coverage
Test: Web Wispers 1.2.2 C++ Unit Tests Lines: 9 36 25.0 %
Date: 2012-04-09 Functions: 7 18 38.9 %
Branches: 4 48 8.3 %

           Branch data     Line data    Source code
       1                 :            : /* Copyright 2006-2009 Savarese Software Research Corporation
       2                 :            :  *
       3                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       4                 :            :  * you may not use this file except in compliance with the License.
       5                 :            :  * You may obtain a copy of the License at
       6                 :            :  *
       7                 :            :  *     https://www.savarese.com/software/ApacheLicense-2.0
       8                 :            :  *
       9                 :            :  * Unless required by applicable law or agreed to in writing, software
      10                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      11                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12                 :            :  * See the License for the specific language governing permissions and
      13                 :            :  * limitations under the License.
      14                 :            :  */
      15                 :            : 
      16                 :            : /**
      17                 :            :  * @file
      18                 :            :  * This header defines the BindProperties class.
      19                 :            :  */
      20                 :            : 
      21                 :            : #ifndef __SSRC_WSPR_UTILITY_BIND_PROPERTIES_H
      22                 :            : #define __SSRC_WSPR_UTILITY_BIND_PROPERTIES_H
      23                 :            : 
      24                 :            : #include <ssrc/wisp/utility/wisp_struct.h>
      25                 :            : #include <ssrc/wispers/utility/Properties.h>
      26                 :            : #include <type_traits>
      27                 :            : 
      28                 :            : __BEGIN_NS_SSRC_WSPR_UTILITY
      29                 :            : 
      30                 :            : // TODO: find a cleaner way to do this.
      31                 :            : template<typename T>
      32                 :            : struct is_bindable {
      33                 :            :   typedef ssrc::wisp::utility::wisp_struct type;
      34                 :            : };
      35                 :            : 
      36                 :            : #define WSPR_IS_BINDABLE_SEQUENCE(T)            \
      37                 :            :   __BEGIN_NS_SSRC_WSPR_UTILITY                  \
      38                 :            :   template<> struct is_bindable<T> {            \
      39                 :            :   typedef property_vector type;                 \
      40                 :            :   };                                            \
      41                 :            :   __END_NS_SSRC_WSPR_UTILITY
      42                 :            : 
      43                 :            : #define WSPR_IS_PRIMITIVE_BINDABLE_SEQUENCE(T)  \
      44                 :            :   __BEGIN_NS_SSRC_WSPR_UTILITY                  \
      45                 :            :   template<> struct is_bindable<T> {            \
      46                 :            :   typedef primitive_property_vector type;       \
      47                 :            :   };                                            \
      48                 :            :   __END_NS_SSRC_WSPR_UTILITY
      49                 :            : 
      50                 :            : /**
      51                 :            :  * BindProperties is used to create temporary function objects for use
      52                 :            :  * with wisp_struct visit() in order to copy wisp_struct member variables
      53                 :            :  * to comparably named Properties values.  For example:
      54                 :            :  * <pre>
      55                 :            :  * WISP_STRUCT(IntPair, ((int, first))((int, second)));
      56                 :            :  * WISP_STRUCT(NestedPair, ((IntPair, first))((IntPair, second)));
      57                 :            :  *
      58                 :            :  * Properties props;
      59                 :            :  * NestedPair pair(IntPair(1, 2), IntPair(3, 4));
      60                 :            :  * const string expected("{first={first=1,second=2},second={first=3,second=4}}");
      61                 :            :  *
      62                 :            :  * pair.visit(BindProperties(props));
      63                 :            :  * assert(expected == to_string(props));
      64                 :            :  * </pre>
      65                 :            :  *
      66                 :            :  * As demonstrated in the example, nested wisp_struct members will be
      67                 :            :  * recursively bound.
      68                 :            :  */
      69                 :            : class BindProperties {
      70                 :            :   Properties & properties;
      71                 :            : 
      72                 :            :   template<typename V>
      73                 :            :   const BindProperties &
      74                 :          8 :   bind(const char * const key, const V & value,
      75                 :            :        const std::false_type&, const ssrc::wisp::utility::wisp_struct&) const
      76                 :            :   {
      77                 :          8 :     properties.set(value, key);
      78                 :          8 :     return *this;
      79                 :            :   }
      80                 :            : 
      81                 :            :   template<typename V>
      82                 :            :   const BindProperties &
      83                 :          2 :   bind(const char * const key, const V & value,
      84                 :            :        const std::true_type&, const ssrc::wisp::utility::wisp_struct&) const
      85                 :            :   {
      86   [ +  -  +  -  :          2 :     value.visit(BindProperties(*properties.create_node(key)));
             +  -  +  - ]
      87                 :          2 :     return *this;
      88                 :            :   }
      89                 :            : 
      90                 :            :   // Support functions for bindable sequence bind.
      91                 :            :   template<typename Iterator>
      92                 :          0 :   static void visit(Iterator & v, Properties & p,
      93                 :            :                     const ssrc::wisp::utility::wisp_struct&)
      94                 :            :   {
      95                 :          0 :     v->visit(BindProperties(p));
      96                 :          0 :   }
      97                 :            : 
      98                 :            :   template<typename Iterator>
      99                 :          0 :   static void visit(Iterator & v, Properties & p,
     100                 :            :                     const primitive_property_vector&)
     101                 :            :   {
     102                 :          0 :     primitive_property_vector & pv = p.create_primitive_property_vector();
     103                 :            : 
     104         [ #  # ]:          0 :     for(typename Iterator::value_type::const_iterator it = v->begin(),
     105                 :          0 :           && end = v->end(); it != end; ++it)
     106                 :            :     {
     107         [ #  # ]:          0 :       pv.push_back(*it);
     108                 :            :     }
     109                 :          0 :   }
     110                 :            : 
     111                 :            :   template<typename Iterator>
     112                 :          0 :   static void visit(Iterator & v, Properties & p, const property_vector&)
     113                 :            :   {
     114                 :          0 :     property_vector & pv = p.create_property_vector();
     115                 :            : 
     116         [ #  # ]:          0 :     for(typename Iterator::value_type::const_iterator it = v->begin(),
     117                 :          0 :           && end = v->end(); it != end; ++it)
     118                 :            :     {
     119         [ #  # ]:          0 :       pv.push_back(new Properties);
     120                 :          0 :       visit(it, pv.back(), typename is_bindable<typename Iterator::value_type::value_type>::type());
     121                 :            :     }
     122                 :          0 :   }
     123                 :            : 
     124                 :            :   // For bindable sequences.
     125                 :            :   template<typename V>
     126                 :            :   const BindProperties &
     127                 :          0 :   bind(const char * const key, const V & value,
     128                 :            :        const std::false_type&, const primitive_property_vector&) const
     129                 :            :   {
     130                 :            :     primitive_property_vector & pv =
     131                 :          0 :       properties.create_primitive_property_vector(key);
     132                 :            : 
     133         [ #  # ]:          0 :     for(typename V::const_iterator it = value.begin(), && end = value.end();
     134                 :            :         it != end; ++it)
     135                 :            :     {
     136         [ #  # ]:          0 :       pv.push_back(*it);
     137                 :            :     }
     138                 :            : 
     139                 :          0 :     return *this;
     140                 :            :   }
     141                 :            : 
     142                 :            :   template<typename V>
     143                 :            :   const BindProperties &
     144                 :          0 :   bind(const char * const key, const V & value,
     145                 :            :        const std::false_type&, const property_vector&) const
     146                 :            :   {
     147                 :          0 :     property_vector & pv = properties.create_property_vector(key);
     148                 :            : 
     149   [ #  #  #  #  :          0 :     for(typename V::const_iterator it = value.begin(), && end = value.end();
                   #  # ]
     150                 :            :         it != end; ++it)
     151                 :            :     {
     152   [ #  #  #  #  :          0 :       pv.push_back(new Properties);
                   #  # ]
     153   [ #  #  #  #  :          0 :       visit(it, pv.back(),
             #  #  #  # ]
     154                 :            :             typename is_bindable<typename V::value_type>::type());
     155                 :            :     }
     156                 :            : 
     157                 :          0 :     return *this;
     158                 :            :   }
     159                 :            : 
     160                 :            : public:
     161                 :            : 
     162                 :            :   /**
     163                 :            :    * Creates a BindProperties instance that will bind values to the specified
     164                 :            :    * Properties argument.
     165                 :            :    *
     166                 :            :    * @param properties A reference to the Properties instance to which
     167                 :            :    *                   values will be bound.
     168                 :            :    */
     169                 :          4 :   explicit BindProperties(Properties & properties) : properties(properties) { }
     170                 :            : 
     171                 :            :   /**
     172                 :            :    * Adds a key-value pair to the associated Properties.
     173                 :            :    *
     174                 :            :    * @param key The name of the variable to bind.
     175                 :            :    * @param value The value of the variable to bind.
     176                 :            :    */
     177                 :            :   template<typename V>
     178                 :            :   const BindProperties &
     179                 :         10 :   operator()(const char * const key, const V & value) const {
     180                 :            :     return bind(key, value,
     181                 :            :                 typename std::is_base_of<ssrc::wisp::utility::wisp_struct, V>::type(),
     182   [ #  #  #  #  :         10 :                 typename is_bindable<V>::type());
             #  #  #  # ]
     183                 :            :   }
     184                 :            : };
     185                 :            : 
     186                 :            : __END_NS_SSRC_WSPR_UTILITY
     187                 :            : 
     188                 :            : #endif