Skip to content
Snippets Groups Projects
Commit afaada95 authored by Ben Cumming's avatar Ben Cumming Committed by GitHub
Browse files

Merge pull request #58 from halfflat/feature/lex-ordering-macro

Add macro to help define lexicographic orderings.
parents c2adfeb4 25a8bc45
No related branches found
No related tags found
No related merge requests found
#pragma once
/*
* Macro definitions for defining comparison operators for
* record-like types.
*
* Use:
*
* To define comparison operations for a record type xyzzy
* with fields foo, bar and baz:
*
* DEFINE_LEXICOGRAPHIC_ORDERING(xyzzy,(a.foo,a.bar,a.baz),(b.foo,b.bar,b.baz))
*
* The explicit use of 'a' and 'b' in the second and third parameters
* is needed only to save a heroic amount of preprocessor macro
* deep magic.
*
*/
#include <tuple>
#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_(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)
......@@ -16,6 +16,7 @@ set(TEST_SOURCES
test_event_queue.cpp
test_fvm.cpp
test_cell_group.cpp
test_lexcmp.cpp
test_matrix.cpp
test_mechanisms.cpp
test_optional.cpp
......
#include "gtest.h"
#include <util/lexcmp_def.hpp>
struct lexcmp_test_one {
int foo;
};
DEFINE_LEXICOGRAPHIC_ORDERING(lexcmp_test_one, (a.foo), (b.foo))
TEST(lexcmp_def,one) {
lexcmp_test_one p{3}, q{4}, r{4};
EXPECT_LE(p,q);
EXPECT_LT(p,q);
EXPECT_NE(p,q);
EXPECT_GE(q,p);
EXPECT_GT(q,p);
EXPECT_LE(q,r);
EXPECT_GE(q,r);
EXPECT_EQ(q,r);
}
struct lexcmp_test_three {
int x;
std::string y;
double z;
};
// test fields in reverse order: z, y, x
DEFINE_LEXICOGRAPHIC_ORDERING(lexcmp_test_three, (a.z,a.y,a.x), (b.z,b.y,b.x))
TEST(lexcmp_def,three) {
lexcmp_test_three p{1,"foo",2};
lexcmp_test_three q{1,"foo",3};
lexcmp_test_three r{1,"bar",2};
lexcmp_test_three s{5,"foo",2};
EXPECT_LE(p,q);
EXPECT_LT(p,q);
EXPECT_NE(p,q);
EXPECT_GE(q,p);
EXPECT_GT(q,p);
EXPECT_LE(r,p);
EXPECT_LT(r,p);
EXPECT_NE(p,r);
EXPECT_GE(p,r);
EXPECT_GT(p,r);
EXPECT_LE(p,s);
EXPECT_LT(p,s);
EXPECT_NE(p,s);
EXPECT_GE(s,p);
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);
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment