1 
2 // Copyright 2005 The Trustees of Indiana University.
3 
4 // Use, modification and distribution is subject to the Boost Software
5 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 
8 //
9 // dynamic_properties_test.cpp - test cases for the dynamic property maps.
10 //
11 
12 //  Author: Ronald Garcia
13 #include <boost/config.hpp>
14 
15 // For Borland, act like BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS is defined
16 #if defined (__BORLANDC__) && (__BORLANDC__ <= 0x570) && !defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
17 #  define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
18 #endif
19 
20 #include <boost/test/minimal.hpp>
21 #include <boost/smart_ptr.hpp>
22 #include <boost/property_map/dynamic_property_map.hpp>
23 #include <boost/property_map/property_map.hpp>
24 #include <map>
25 #include <iostream>
26 #include <string>
27 #include <memory>
28 
29 // generate a dynamic_property_map that maps strings to strings
30 // WARNING: This code leaks memory.  For testing purposes only!
31 // WARNING: This code uses library internals. For testing purposes only!
32 boost::shared_ptr<boost::dynamic_property_map>
string2string_gen(const std::string & name,const boost::any &,const boost::any &)33 string2string_gen(const std::string& name,
34                   const boost::any&,
35                   const boost::any&) {
36   typedef std::map<std::string,std::string> map_t;
37   typedef
38     boost::associative_property_map< std::map<std::string, std::string> >
39     property_t;
40 
41 
42   map_t* mymap = new map_t(); // hint: leaky memory here!
43 
44   property_t property_map(*mymap);
45 
46   boost::shared_ptr<boost::dynamic_property_map> pm(
47     new
48     boost::detail::dynamic_property_map_adaptor<property_t>(property_map));
49 
50   return pm;
51 }
52 
53 
test_main(int,char **)54 int test_main(int,char**) {
55 
56   // build property maps using associative_property_map
57 
58   std::map<std::string, int> string2int;
59   std::map<double,std::string> double2string;
60   boost::associative_property_map< std::map<std::string, int> >
61     int_map(string2int);
62   boost::associative_property_map< std::map<double, std::string> >
63     dbl_map(double2string);
64 
65 
66   // add key-value information
67   string2int["one"] = 1;
68   string2int["five"] = 5;
69 
70   double2string[5.3] = "five point three";
71   double2string[3.14] = "pi";
72 
73 
74   // build and populate dynamic interface
75   boost::dynamic_properties properties;
76   properties.property("int",int_map);
77   properties.property("double",dbl_map);
78 
79   using boost::get;
80   using boost::put;
81   using boost::type;
82   // Get tests
83   {
84     BOOST_CHECK(get("int",properties,std::string("one")) == "1");
85 #ifndef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
86     BOOST_CHECK(boost::get<int>("int",properties,std::string("one")) == 1);
87 #endif
88     BOOST_CHECK(get("int",properties,std::string("one"), type<int>()) == 1);
89     BOOST_CHECK(get("double",properties,5.3) == "five point three");
90   }
91 
92   // Put tests
93   {
94     put("int",properties,std::string("five"),6);
95     BOOST_CHECK(get("int",properties,std::string("five")) == "6");
96     put("int",properties,std::string("five"),std::string("5"));
97 #ifndef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
98     BOOST_CHECK(get<int>("int",properties,std::string("five")) == 5);
99 #endif
100     BOOST_CHECK(get("int",properties,std::string("five"),type<int>()) == 5);
101     put("double",properties,3.14,std::string("3.14159"));
102     BOOST_CHECK(get("double",properties,3.14) == "3.14159");
103     put("double",properties,3.14,std::string("pi"));
104 #ifndef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
105     BOOST_CHECK(get<std::string>("double",properties,3.14) == "pi");
106 #endif
107     BOOST_CHECK(get("double",properties,3.14,type<std::string>()) == "pi");
108   }
109 
110   // Nonexistent property
111   {
112     try {
113       get("nope",properties,3.14);
114       BOOST_ERROR("No exception thrown.");
115     } catch (boost::dynamic_get_failure&) { }
116 
117     try {
118       put("nada",properties,3.14,std::string("3.14159"));
119       BOOST_ERROR("No exception thrown.");
120     } catch (boost::property_not_found&) { }
121   }
122 
123   // Nonexistent property gets generated
124   {
125     boost::dynamic_properties props(&string2string_gen);
126     put("nada",props,std::string("3.14"),std::string("pi"));
127     BOOST_CHECK(get("nada",props,std::string("3.14"))  == "pi");
128   }
129 
130   // Use the ignore_other_properties generator
131   {
132     boost::dynamic_properties props(&boost::ignore_other_properties);
133     bool value = put("nada",props,std::string("3.14"),std::string("pi"));
134     BOOST_CHECK(value == false);
135   }
136 
137   return boost::exit_success;
138 }
139