text: ////////////////////////////////////////////////////////////////////////////////
  //  Copyright (c) 2013 Shuangyang Yang
  //
  //  SPDX-License-Identifier: BSL-1.0
  //  Distributed under 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)
  ////////////////////////////////////////////////////////////////////////////////
  
  #pragma once
  
  #include <hpx/serialization/serialize.hpp>
  
  #include <cstdint>
  #include <iostream>
  
  #define ENABLE_DEBUG false
  
  ///////////////////////////////////////////////////////////////////////////////
  struct small_object
  {
    private:
      std::uint64_t x_;
  
      friend class hpx::serialization::access;
  
      template <
          typename Archive
      >
      void serialize(
          Archive& ar
        , unsigned const
          )
      {
          ar & x_;
  
          if(ENABLE_DEBUG)
          {
              std::cout << "small_object: serialize(" << x_ << ")\n";
          }
      }
  
    public:
      small_object()
        : x_(0)
      {
          if(ENABLE_DEBUG)
          {
              std::cout << "small_object: default ctor\n";
          }
      }
  
      small_object(
          std::uint64_t x
          )
        : x_(x)
      {
          if(ENABLE_DEBUG)
          {
              std::cout << "small_object: ctor(" << x << ")\n";
          }
      }
  
      small_object(
          small_object const& o
          )
        : x_(o.x_)
      {
          if(ENABLE_DEBUG)
          {
              std::cout << "small_object: copy(" << o.x_ << ")\n";
          }
      }
  
      small_object& operator=(
          small_object const& o
          )
      {
          x_ = o.x_;
          if(ENABLE_DEBUG)
          {
              std::cout << "small_object: assign(" << o.x_ << ")\n";
          }
          return *this;
      }
  
      bool operator==(
          small_object const& o
          ) const
      {
          if(ENABLE_DEBUG)
          {
              std::cout << "small_object: equal(" << o.x_ << ")\n";
          }
          return x_ == o.x_;
      }
  
      ~small_object()
      {
          if(ENABLE_DEBUG)
          {
              std::cout << "small_object: dtor(" << x_ << ")\n";
          }
      }
  
      std::uint64_t operator()(
          std::uint64_t const& z_
          )
      {
          if(ENABLE_DEBUG)
          {
              std::cout << "small_object: call(" << x_ << ", " << z_ << ")\n";
          }
          return x_ + z_;
      }
  
  
      friend inline std::istream&
      operator>> (std::istream& in, small_object& obj)
      {
          in >> obj.x_;
          if(ENABLE_DEBUG)
          {
              std::cout << "small_object: istream ("<< obj.x_ << ")\n";
          }
  
          return in;
      }
  
      friend inline std::ostream&
      operator<< (std::ostream& out, small_object const& obj)
      {
          out << obj.x_;
          if(ENABLE_DEBUG)
          {
              std::cout << "small_object: ostream ("<< obj.x_ << ")\n";
          }
  
          return out;
      }
  };
  
  ///////////////////////////////////////////////////////////////////////////////
  struct big_object
  {
    private:
      std::uint64_t x_;
      std::uint64_t y_;
  
      friend class hpx::serialization::access;
  
      template <
          typename Archive
      >
      void serialize(
          Archive& ar
        , unsigned const
          )
      {
          ar & x_;
          ar & y_;
          if(ENABLE_DEBUG)
          {
              std::cout << "big_object: serialize(" << x_ << ", " << y_ << ")\n";
          }
      }
  
    public:
      big_object()
        : x_(0)
        , y_(0)
      {
          if(ENABLE_DEBUG)
          {
              std::cout << "big_object: default ctor\n";
          }
      }
  
      big_object(
          std::uint64_t x
        , std::uint64_t y
          )
        : x_(x)
        , y_(y)
      {
          if(ENABLE_DEBUG)
          {
              std::cout << "big_object: ctor(" << x << ", " << y << ")\n";
          }
      }
  
      big_object(
          big_object const& o
          )
        : x_(o.x_)
        , y_(o.y_)
      {
          if(ENABLE_DEBUG)
          {
              std::cout << "big_object: copy(" << o.x_ << ", " << o.y_ << ")\n";
          }
      }
  
      big_object& operator=(
          big_object const& o
          )
      {
          x_ = o.x_;
          y_ = o.y_;
          if(ENABLE_DEBUG)
          {
              std::cout << "big_object: assign(" << o.x_ << ", " << o.y_ << ")\n";
          }
          return *this;
      }
  
      bool operator==(
          big_object const& o
          ) const
      {
          if(ENABLE_DEBUG)
          {
              std::cout << "big_object: equal(" << o.x_ << ", " << o.y_ << ")\n";
          }
          return ((x_ == o.x_) && (y_ == o.y_));
      }
  
      ~big_object()
      {
          if(ENABLE_DEBUG)
          {
              std::cout << "big_object: dtor(" << x_ << ", " << y_ << ")\n";
          }
      }
  
      std::uint64_t operator()(
          std::uint64_t const& z_
        , std::uint64_t const& w_
          )
      {
          if(ENABLE_DEBUG)
          {
              std::cout << "big_object: call(" << x_ << ", " << y_
                    << ", " << z_ << ", " << w_ << ")\n";
          }
          return x_ + y_ + z_ + w_;
      }
  
      friend inline std::istream&
      operator>> (std::istream& in, big_object& obj)
      {
          in >> obj.x_;
          in >> obj.y_;
          if(ENABLE_DEBUG)
          {
              std::cout << "big_object: istream ("<< obj.x_ <<", "<< obj.y_ << ")\n";
          }
  
          return in;
      }
  
      friend inline std::ostream&
      operator<< (std::ostream& out, big_object const& obj)
      {
          out << obj.x_;
          out << obj.y_;
          if(ENABLE_DEBUG)
          {
              std::cout << "big_object: ostream ("<< obj.x_ <<", "<< obj.y_ << ")\n";
          }
  
          return out;
      }
  };
  
  #undef ENABLE_DEBUG
  