Learn » Examples » Non-Intrusive Program Example 3

The full code for this magistrate example can be found here: examples/checkpoint_example_3_nonintrusive.cc

Example source code:

#include <checkpoint/checkpoint.h>

#include <cstdio>

//
// This example illustrates how checkpoint uses traits to determine a
// reconstruction strategy and shows several mechanisms for reconstructing a
// class of a serializable/deserializable type.
//

// \brief Namespace containing types which will be serialized
namespace checkpoint { namespace nonintrusive { namespace examples {

// \brief Structure with a variable of built-in type.
struct TestDefaultCons {
  int a = 29;

  TestDefaultCons() = default;
};

// \brief Structure with a variable of built-in type.
//
// \note This structure is a byte-serializable/deserializable type but doesn't
// contain any traits to indicate that making it not serializable.
//
struct TestNoSerialize {
  int a = 29;
};

// \brief Structure with a variable of built-in type.
//
// \note This structure is not a serializable / deserializable type. The
// structure has an explicitly deleted default constructor and a constructor
// that takes an `int` parameter.  Serialization has no way to construct the
// structure.
struct TestShouldFailReconstruct {
  int a = 29;

  explicit TestShouldFailReconstruct(int const) { }
  TestShouldFailReconstruct() = delete;
};

// \brief Structure with a variable of built-in type.
//
// \note This structure is a serializable / deserializable type. The structure
// has an explicitly deleted default constructor and a constructor that takes an
// `int` parameter. However, the structure provides a static reconstruct
// method that serialization can use to construct the structure.
struct TestReconstruct {
  int a = 29;

  explicit TestReconstruct(int const) { }
  TestReconstruct() = delete;

  static TestReconstruct& reconstruct(void* buf) {
    auto a = new (buf) TestReconstruct(100);
    return *a;
  }
};

}}} // end namespace checkpoint::nonintrusive::examples

// \brief In Non-Intrusive way, serialize function needs to be placed in the namespace
// of the type which will be serialized.
namespace checkpoint { namespace nonintrusive { namespace examples {

// \brief Non-Intrusive Serialize method for TestDefaultCons structure.
//
// \note Together with default constructor provides a serialization / deserialization
// capability to the structure.
template <typename Serializer>
void serialize(Serializer& s, TestDefaultCons& tdc) {
  s | tdc.a;
}

// \brief Non-Intrusive Serialize method for TestShouldFailReconstruct structure.
template <typename Serializer>
void serialize(Serializer& s, TestShouldFailReconstruct& tsf) {
  s | tsf.a;
}

// \brief Non-Intrusive Serialize method for TestReconstruct structure.
template <typename Serializer>
void serialize(Serializer& s, TestReconstruct& tr) {
  s | tr.a;
}

}}} // end namespace checkpoint::nonintrusive::examples

#include "checkpoint/traits/serializable_traits.h"

namespace checkpoint {

using namespace nonintrusive::examples;

static_assert(
  SerializableTraits<TestDefaultCons>::is_serializable,
  "Should be serializable"
);
static_assert(
  ! SerializableTraits<TestNoSerialize>::is_serializable,
  "Should not be serializable"
);

static_assert(
  ! SerializableTraits<TestShouldFailReconstruct>::is_serializable,
  "Should not be serializable"
);

static_assert(
  SerializableTraits<TestReconstruct>::is_serializable,
  "Should be serializable"
);

} // end namespace checkpoint


int main(int, char**) {
  // Example is a compile-time test of serializability traits
  return 0;
}