diff --git a/src/util/lexcmp_def.hpp b/src/util/lexcmp_def.hpp
index 0cc7e66d0b9cdce347a7b5bac9d89fb50fe0de5b..d1c3e8a3bfc63341070b55b1320de03583797bbe 100644
--- a/src/util/lexcmp_def.hpp
+++ b/src/util/lexcmp_def.hpp
@@ -19,13 +19,22 @@
 
 #include <tuple>
 
-#define DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(op,type,a_fields,b_fields) \
-inline bool operator op(const type &a,const type &b) { return std::tie a_fields op std::tie b_fields; }
+#define DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(proxy,op,type,a_fields,b_fields) \
+inline bool operator op(const type &a,const type &b) { return proxy a_fields op proxy b_fields; }
 
 #define DEFINE_LEXICOGRAPHIC_ORDERING(type,a_fields,b_fields) \
-DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(<,type,a_fields,b_fields) \
-DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(>,type,a_fields,b_fields) \
-DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(<=,type,a_fields,b_fields) \
-DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(>=,type,a_fields,b_fields) \
-DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(!=,type,a_fields,b_fields) \
-DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(==,type,a_fields,b_fields)
+DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(std::tie,<,type,a_fields,b_fields) \
+DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(std::tie,>,type,a_fields,b_fields) \
+DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(std::tie,<=,type,a_fields,b_fields) \
+DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(std::tie,>=,type,a_fields,b_fields) \
+DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(std::tie,!=,type,a_fields,b_fields) \
+DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(std::tie,==,type,a_fields,b_fields)
+
+#define DEFINE_LEXICOGRAPHIC_ORDERING_BY_VALUE(type,a_fields,b_fields) \
+DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(std::make_tuple,<,type,a_fields,b_fields) \
+DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(std::make_tuple,>,type,a_fields,b_fields) \
+DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(std::make_tuple,<=,type,a_fields,b_fields) \
+DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(std::make_tuple,>=,type,a_fields,b_fields) \
+DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(std::make_tuple,!=,type,a_fields,b_fields) \
+DEFINE_LEXICOGRAPHIC_ORDERING_IMPL_(std::make_tuple,==,type,a_fields,b_fields)
+
diff --git a/tests/unit/test_lexcmp.cpp b/tests/unit/test_lexcmp.cpp
index 300372391de1d69016eec827cf03ef1e46c30dfb..a02ac0765823f61d54e8acee3cf38611552d9dd7 100644
--- a/tests/unit/test_lexcmp.cpp
+++ b/tests/unit/test_lexcmp.cpp
@@ -56,3 +56,55 @@ TEST(lexcmp_def,three) {
     EXPECT_GT(s,p);
 }
 
+// test fields accessed by reference-returning member function
+
+class lexcmp_test_refmemfn {
+public:
+    explicit lexcmp_test_refmemfn(int foo): foo_(foo) {}
+
+    const int &foo() const { return foo_; }
+    int &foo() { return foo_; }
+
+private:
+    int foo_;
+};
+
+DEFINE_LEXICOGRAPHIC_ORDERING(lexcmp_test_refmemfn, (a.foo()), (b.foo()))
+
+TEST(lexcmp_def,refmemfn) {
+    lexcmp_test_refmemfn p{3};
+    const lexcmp_test_refmemfn q{4};
+
+    EXPECT_LE(p,q);
+    EXPECT_LT(p,q);
+    EXPECT_NE(p,q);
+    EXPECT_GE(q,p);
+    EXPECT_GT(q,p);
+}
+
+// test comparison via proxy tuple object
+
+class lexcmp_test_valmemfn {
+public:
+    explicit lexcmp_test_valmemfn(int foo, int bar): foo_(foo), bar_(bar) {}
+    int foo() const { return foo_; }
+    int bar() const { return bar_; }
+
+private:
+    int foo_;
+    int bar_;
+};
+
+DEFINE_LEXICOGRAPHIC_ORDERING_BY_VALUE(lexcmp_test_valmemfn, (a.foo(),a.bar()), (b.foo(),b.bar()))
+
+TEST(lexcmp_def,proxy) {
+    lexcmp_test_valmemfn p{3,2}, q{3,4};
+
+    EXPECT_LE(p,q);
+    EXPECT_LT(p,q);
+    EXPECT_NE(p,q);
+    EXPECT_GE(q,p);
+    EXPECT_GT(q,p);
+}
+
+