Variant with Mach7

#include <mach7/type_switchN-patterns-xtl.hpp>  // Match()
#include <mach7/adapters/boost/adapt_boost_variant.hpp>
#include <mach7/patterns/constructor.hpp>       // mch::C
#include <mach7/patterns/primitive.hpp>         // mch::var

#include <boost/variant.hpp>
#include <vector>

using std::vector;
typedef int Id, BallastType;
typedef double Volume, Weight, Distrib;

struct Container
{
  Volume volume_allowance;
  Weight weight_allowance;
  bool is_air_conditioned;
  Id id;
  // more ...
};

struct MultiContainer
{
  vector<Container> containers;
  Id id;
  // more ...
};

struct Ballast
{
  BallastType type;
  Weight weight;
  // more ...
};

using Block =
  boost::variant<Ballast, Container, MultiContainer>;

struct Bundle
{
  Weight weight;
  Volume volume;
  Id id;
  bool requires_air_conditioning;
  // more ...
};

struct MultiBundle
{
  vector<Bundle> bundles;
  Id bundle_id;
  // more ...
};

using LoadPiece = boost::variant<Bundle, MultiBundle>;

using mch::C; // a 'constructor pattern'

Weight weight_allowance(const Block& block)
{
  Match (block)
  {
  Case (C<Container>())
    return match0.weight_allowance;

  Case (C<MultiContainer>())
    Weight wgt(0);
    for (const Container& cont : match0.containers)
      wgt += cont.weight_allowance;
    return wgt;

  Case (C<Ballast>())
    return Weight(0);
  }
  EndMatch
}

bool fits(const Block& block, const LoadPiece& load)
{
  Match (block, load)
  {
  Case (C<Container>(), C<Bundle>())
    return match0.weight_allowance >= match1.weight
        && match0.volume_allowance >= match1.volume;

  Case (C<Container>(), C<MultiBundle>())
    return bool("sum of bundles fits into c");

  Case (C<MultiContainer>(), C<Bundle>())
    for (const Container& c : match0.containers)
      if (fits(c, match1))
        return true;
    return false;

  Case (C<MultiContainer>(), C<MultiBundle>())
    return bool("all bundles fit across all sub containers");

  Case (C<Ballast>(), C<Bundle>())
    return false;

  Case (C<Ballast>(), C<MultiBundle>())
    return false;
  }
  EndMatch
}

int main()
{
  Block b = Container();
  LoadPiece l = Bundle();
  Weight wgt = weight_allowance(b);
  bool   fit = fits(b, l);
}
Advertisements