Skip to content

Commit fc51b0e

Browse files
authored
Merge pull request #115 from ashtum/delete-get_child-overloads-that-accept-temporaries
Prevent calls to get_child with temporary default values
2 parents 71dd658 + 5438bf7 commit fc51b0e

File tree

3 files changed

+31
-8
lines changed

3 files changed

+31
-8
lines changed

include/boost/property_tree/ptree.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,10 @@ namespace boost { namespace property_tree
270270
const self_type &get_child(const path_type &path,
271271
const self_type &default_value) const;
272272

273+
/** Prevents calls to get_child with temporary default values */
274+
void get_child(const path_type &path,
275+
const self_type &&default_value) const = delete;
276+
273277
/** Get the child at the given path, or return boost::null. */
274278
optional<self_type &> get_child_optional(const path_type &path);
275279

test/test_property_tree.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// ----------------------------------------------------------------------------
1010
#include "test_utils.hpp"
1111
#include <boost/any.hpp>
12+
#include <boost/mp11.hpp>
1213
#include <boost/range.hpp>
1314
#include <list>
1415
#include <cmath>
@@ -67,6 +68,11 @@ struct any_translator
6768
}
6869
};
6970

71+
// Checks the validity of calling get_child with a default value type
72+
template<class P, class C, class D>
73+
using get_child_accepts_default_of_type = decltype(
74+
std::declval<P>().get_child(std::declval<const C*>(), std::declval<D>()));
75+
7076
namespace boost { namespace property_tree {
7177
template <typename E>
7278
struct translator_between<boost::any, E>

test/test_property_tree.hpp

+21-8
Original file line numberDiff line numberDiff line change
@@ -820,14 +820,27 @@ void test_get_child_put_child(PTREE *)
820820
BOOST_TEST(cpt2.get_child(T("k2.k")) == pt);
821821

822822
// Do correct extractions via get_child (default value version)
823-
BOOST_TEST(pt1.get_child(T("k1"), PTREE(T("def"))) != PTREE(T("def")));
824-
BOOST_TEST(pt1.get_child(T("k2.k"), PTREE(T("def"))) != PTREE(T("def")));
825-
BOOST_TEST(pt2.get_child(T("k1"), PTREE(T("def"))) == pt);
826-
BOOST_TEST(pt2.get_child(T("k2.k"), PTREE(T("def"))) == pt);
827-
BOOST_TEST(cpt1.get_child(T("k1"), PTREE(T("def"))) != PTREE(T("def")));
828-
BOOST_TEST(cpt1.get_child(T("k2.k"), PTREE(T("def"))) != PTREE(T("def")));
829-
BOOST_TEST(cpt2.get_child(T("k1"), PTREE(T("def"))) == pt);
830-
BOOST_TEST(cpt2.get_child(T("k2.k"), PTREE(T("def"))) == pt);
823+
PTREE dflt(T("def"));
824+
BOOST_TEST(pt1.get_child(T("k1"), dflt) != dflt);
825+
BOOST_TEST(pt1.get_child(T("k2.k"), dflt) != dflt);
826+
BOOST_TEST(pt2.get_child(T("k1"), dflt) == pt);
827+
BOOST_TEST(pt2.get_child(T("k2.k"), dflt) == pt);
828+
BOOST_TEST(cpt1.get_child(T("k1"), dflt) != dflt);
829+
BOOST_TEST(cpt1.get_child(T("k2.k"), dflt) != dflt);
830+
BOOST_TEST(cpt2.get_child(T("k1"), dflt) == pt);
831+
BOOST_TEST(cpt2.get_child(T("k2.k"), dflt) == pt);
832+
833+
// Ensure that get_child does not compile when using temporaries as the default value.
834+
BOOST_TEST((!boost::mp11::mp_valid<get_child_accepts_default_of_type, const PTREE&, CHTYPE, PTREE>::value));
835+
BOOST_TEST((!boost::mp11::mp_valid<get_child_accepts_default_of_type, const PTREE&, CHTYPE, const PTREE>::value));
836+
BOOST_TEST((!boost::mp11::mp_valid<get_child_accepts_default_of_type, PTREE&, CHTYPE, PTREE>::value));
837+
BOOST_TEST((!boost::mp11::mp_valid<get_child_accepts_default_of_type, PTREE&, CHTYPE, const PTREE>::value));
838+
839+
// Test get_child_accepts_default_of_type itself
840+
BOOST_TEST((boost::mp11::mp_valid<get_child_accepts_default_of_type, const PTREE&, CHTYPE, PTREE&>::value));
841+
BOOST_TEST((boost::mp11::mp_valid<get_child_accepts_default_of_type, const PTREE&, CHTYPE, const PTREE&>::value));
842+
BOOST_TEST((boost::mp11::mp_valid<get_child_accepts_default_of_type, PTREE&, CHTYPE, PTREE&>::value));
843+
BOOST_TEST((boost::mp11::mp_valid<get_child_accepts_default_of_type, PTREE&, CHTYPE, const PTREE&>::value));
831844

832845
// Do correct extractions via get_child (optional version)
833846
boost::optional<PTREE &> opt;

0 commit comments

Comments
 (0)