Finish CRTP in Cyclic

release/4.3a0
dellaert 2014-12-07 15:59:31 +01:00
parent ef58a8a56a
commit 19c38b91ee
2 changed files with 34 additions and 15 deletions

View File

@ -20,21 +20,39 @@
namespace gtsam {
/// Additive Group
/// Additive Group, using CRTP
template<typename Derived>
class AdditiveGroup {
struct AdditiveGroup {
static Derived Identity() {
return Derived::Identity();
}
Derived const * derived() const {
return static_cast<Derived const*>(this);
}
Derived operator+(const AdditiveGroup& h) const {
return derived()->operator+(*h.derived());
}
Derived operator-(const AdditiveGroup& h) const {
return derived()->operator-(*h.derived());
}
Derived operator-() const {
return derived()->operator-();
}
};
/// Cyclic group of order N
template<size_t N>
class Cyclic : AdditiveGroup<Cyclic<N> > {
class Cyclic : public AdditiveGroup<Cyclic<N> > {
size_t i_; ///< we just use an unsigned int
public:
/// Constructor
Cyclic(size_t i) :
i_(i) {
}
// Idenity element
static Cyclic Identity() {
return Cyclic(0);
}
/// Cast to size_t
operator size_t() const {
return i_;
@ -64,8 +82,9 @@ public:
};
namespace traits {
/// Define Cyclic to be a model of the Group concept
template<size_t N> struct structure_category<Cyclic<N> > {
/// Define any additive group to be at least a model of the Group concept
template<typename G>
struct structure_category<AdditiveGroup<G> > {
typedef group_tag type;
};
} // \namespace gtsam::traits
@ -73,30 +92,30 @@ template<size_t N> struct structure_category<Cyclic<N> > {
namespace group {
template<typename G>
AdditiveGroup<G> compose(const AdditiveGroup<G>&g, const AdditiveGroup<G>& h) {
G compose(const AdditiveGroup<G>&g, const AdditiveGroup<G>& h) {
return g + h;
}
template<typename G>
AdditiveGroup<G> between(const AdditiveGroup<G>&g, const AdditiveGroup<G>& h) {
G between(const AdditiveGroup<G>&g, const AdditiveGroup<G>& h) {
return h - g;
}
template<typename G>
AdditiveGroup<G> inverse(const AdditiveGroup<G>&g) {
G inverse(const AdditiveGroup<G>&g) {
return -g;
}
namespace traits {
/// Define the trait that specifies Cyclic's identity element
template<size_t N> struct identity<Cyclic<N> > {
static const Cyclic<N> value;
typedef Cyclic<N> value_type;
template<typename G> struct identity<AdditiveGroup<G> > {
static const G value;
typedef G value_type;
};
template<size_t N>
const Cyclic<N> identity<Cyclic<N> >::value = Cyclic<N>(0);
template<typename G>
const G identity<AdditiveGroup<G> >::value = AdditiveGroup<G>::Identity();
/// Define the trait that asserts AdditiveGroup is an additive group
template<typename G> struct flavor<AdditiveGroup<G> > {

View File

@ -27,7 +27,7 @@ typedef Cyclic<6> G; // Let's use the cyclic group of order 6
//******************************************************************************
TEST(Cyclic, Concept) {
// BOOST_CONCEPT_ASSERT((IsGroup<G>));
BOOST_CONCEPT_ASSERT((AdditiveGroup<G>));
// BOOST_CONCEPT_ASSERT((IsGroup<AdditiveGroup<G> >));
EXPECT_LONGS_EQUAL(0, group::traits::identity<G>::value);
G g(2), h(3);
// EXPECT(Group<G>().check_invariants(g,h))