diff --git a/include/boost/geometry/index/query_expr.hpp b/include/boost/geometry/index/query_expr.hpp new file mode 100644 index 000000000..750fab90b --- /dev/null +++ b/include/boost/geometry/index/query_expr.hpp @@ -0,0 +1,61 @@ +// Boost.Geometry Index +// +// Query expr +// +// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_INDEX_QUERY_EXPR_HPP +#define BOOST_GEOMETRY_INDEX_QUERY_EXPR_HPP + +#include +#include + +namespace boost { namespace geometry { namespace index { namespace qe { + +// tags + +struct intersects_tag {}; +struct within_tag {}; + +struct nearest_tag {}; + +// predicates + +template +struct predicate +{ + typedef Tag tag_type; + predicate(T const& d) : data(d) {} + T const& data; +}; + +template +struct predicate +{ + typedef nearest_tag tag_type; + predicate(T const& d, size_t k) : data(d), count(k) {} + T const& data; + size_t count; +}; + +// predicates generators + +template +predicate intersects(Geometry const& g) +{ + return predicate(g); +} + +template +predicate nearest(DistancePredicates const& p, size_t k) +{ + return predicate(p, k); +} + +}}}} // namespace boost::geometry::index::qe + +#endif // BOOST_GEOMETRY_INDEX_QUERY_EXPR_HPP diff --git a/tests/query_expr.cpp b/tests/query_expr.cpp new file mode 100644 index 000000000..8e33989f8 --- /dev/null +++ b/tests/query_expr.cpp @@ -0,0 +1,211 @@ +// Boost.Geometry Index +// Additional tests + +// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +#include +#include +#include + +template +struct Test +{ + inline Test(T const& t) : v(t) {} + T v; +}; + +template +struct Raw +{ + inline explicit Raw(T1 const& t1, T2 const& t2, T3 const& t3) : v1(t1), v2(t2), v3(t3) {} + T1 v1; + T2 v2; + T3 v3; +}; + +template inline +boost::tuples::cons< + Test, + boost::tuples::cons, boost::tuples::null_type> +> +operator&&(Test const& t1, Test const& t2) +{ + return + boost::tuples::cons< + Test, + boost::tuples::cons, boost::tuples::null_type> + >(t2, + boost::tuples::cons, boost::tuples::null_type>(t1, boost::tuples::null_type()) + ); +} + +template inline +boost::tuples::cons< + Test, + boost::tuples::cons +> +operator&&(boost::tuples::cons const& t, Test const& t2) +{ + return + boost::tuples::cons< + Test, + boost::tuples::cons + >(t2, t); +} + +template +struct Test2 +{ + inline Test2(T const& t) : v(t) {} + T v; +}; + +template inline +boost::tuples::cons< + Test2, + boost::tuples::cons, boost::tuples::null_type> +> +operator&&(Test2 const& t1, Test2 const& t2) +{ + return + boost::tuples::cons< + Test2, + boost::tuples::cons, boost::tuples::null_type> + >(t1, + boost::tuples::cons, boost::tuples::null_type>(t2, boost::tuples::null_type()) + ); +} + +template +struct add +{ + typedef + boost::tuples::cons< + typename boost::tuples::element::type, + typename add::type + > type; + + static type apply(T const& t, Tuple const& tup) + { + return + type( + boost::get(tup), + add::apply(t, tup) + ); + } +}; + +template +struct add +{ + typedef boost::tuples::cons type; + + static type apply(T const& t, Tuple const&) + { + return type(t, boost::tuples::null_type()); + } +}; + +template inline +typename add< + Test2, + boost::tuples::cons, + 0, + boost::tuples::length >::value +>::type +operator&&(boost::tuples::cons const& t, Test2 const& t2) +{ + return + add< + Test2, + boost::tuples::cons, + 0, + boost::tuples::length >::value + >::apply(t2, t); +} + +template inline +double test(T const& t) +{ + return boost::get<0>(t).v + boost::get<1>(t).v + boost::get<2>(t).v; +} + +int main() +{ + using namespace boost::geometry::index::qe; + + boost::timer tim; + + size_t count = 200000000; + int dummy = 0; + std::ifstream f("blablabla"); + f >> dummy; + + std::cout << "&&1 &&2 b, r,\n"; + + double sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0; + for(size_t i = 0 ; i < 20; ++i) + { + double foo = 0; + + { + tim.restart(); + for ( size_t i = 0 ; i < count ; ++i ) + { + foo += test(Test(dummy) && Test(dummy) && Test(dummy)); + } + double t = tim.elapsed(); + sum1 += t; + std::cout << t << ' '; + } + + { + tim.restart(); + for ( size_t i = 0 ; i < count ; ++i ) + { + foo += test(Test2(dummy) && Test2(dummy) && Test2(dummy)); + } + double t = tim.elapsed(); + sum2 += t; + std::cout << t << ' '; + } + + { + tim.restart(); + for ( size_t i = 0 ; i < count ; ++i ) + { + boost::tuple, Test, Test > tup + = boost::make_tuple(Test(dummy), Test(dummy), Test(dummy)); + foo += boost::get<0>(tup).v + boost::get<1>(tup).v + boost::get<2>(tup).v; + } + double t = tim.elapsed(); + sum3 += t; + std::cout << t << ' '; + } + + { + tim.restart(); + for ( size_t i = 0 ; i < count ; ++i ) + { + Raw, Test, Test > tup(dummy, dummy, dummy); + foo += tup.v1.v + tup.v2.v + tup.v3.v; + } + double t = tim.elapsed(); + sum4 += t; + std::cout << t << ' '; + } + + std::cout << foo << '\n'; + } + + std::cout << "sums:\n"; + std::cout << sum1 << " " << sum2 << " " << sum3 << " " << sum4; + + return 0; +}