<commit_before>/******************************************************************************\
 * This example is a very basic, non-interactive math service implemented     *
 * for both the blocking and the event-based API.                             *
\ ******************************************************************************/

#include <tuple>
#include <cassert>
#include <iostream>

#include "caf/all.hpp"

using std::cout;
using std::endl;
using namespace caf;

using plus_atom = atom_constant<atom("plus")>;
using minus_atom = atom_constant<atom("minus")>;

// implementation using the blocking API
void blocking_calculator(blocking_actor* self) {
  self->receive_loop (
    [](plus_atom, int a, int b) {
      return a + b;
    },
    [](minus_atom, int a, int b) {
      return a - b;
    },
    others >> [=] {
      cout << "unexpected: " << to_string(self->current_message()) << endl;
    }
  );
}

// execute this behavior until actor terminates
behavior calculator(event_based_actor* self) {
  return behavior{
    [](plus_atom, int a, int b) {
      return a + b;
    },
    [](minus_atom, int a, int b) {
      return a - b;
    },
    others >> [=] {
      cout << "unexpected: " << to_string(self->current_message()) << endl;
    }
  };
}

void tester(event_based_actor* self, const actor& testee) {
  self->link_to(testee);
  // will be invoked if we receive an unexpected response message
  self->on_sync_failure([=] {
    aout(self) << "AUT (actor under test) failed" << endl;
    self->quit(exit_reason::user_shutdown);
  });
  // first test: 2 + 1 = 3
  self->sync_send(testee, plus_atom::value, 2, 1).then(
    on(3) >> [=] {
      // second test: 2 - 1 = 1
      self->sync_send(testee, minus_atom::value, 2, 1).then(
        on(1) >> [=] {
          // both tests succeeded
          aout(self) << "AUT (actor under test) seems to be ok" << endl;
          self->quit(exit_reason::user_shutdown);
        }
      );
    }
  );
}

int main() {
  cout << "test blocking actor" << endl;
  spawn(tester, spawn<blocking_api>(blocking_calculator));
  await_all_actors_done();
  cout << "test event-based actor" << endl;
  spawn(tester, spawn(calculator));
  await_all_actors_done();
  shutdown();
}<commit_msg>Improve calculator example<commit_after>/******************************************************************************\
 * This example is a very basic, non-interactive math service implemented     *
 * for both the blocking and the event-based API.                             *
\ ******************************************************************************/

#include <tuple>
#include <cassert>
#include <iostream>

#include "caf/all.hpp"

using std::cout;
using std::cerr;
using std::endl;
using namespace caf;

using plus_atom = atom_constant<atom("plus")>;
using minus_atom = atom_constant<atom("minus")>;
using result_atom = atom_constant<atom("result")>;

using calculator_actor =
  typed_actor<replies_to<plus_atom, int, int>::with<result_atom, int>,
              replies_to<minus_atom, int, int>::with<result_atom, int>>;

// implementation using the blocking API
void blocking_calculator(blocking_actor* self) {
  self->receive_loop (
    [](plus_atom, int a, int b) {
      return std::make_tuple(result_atom::value, a + b);
    },
    [](minus_atom, int a, int b) {
      return std::make_tuple(result_atom::value, a - b);
    },
    others >> [=] {
      cout << "unexpected: " << to_string(self->current_message()) << endl;
    }
  );
}

// implementation using the event-based API
behavior calculator(event_based_actor* self) {
  return behavior{
    [](plus_atom, int a, int b) {
      return std::make_tuple(result_atom::value, a + b);
    },
    [](minus_atom, int a, int b) {
      return std::make_tuple(result_atom::value, a - b);
    },
    others >> [=] {
      cerr << "unexpected: " << to_string(self->current_message()) << endl;
    }
  };
}

// implementation using the statically typed API
calculator_actor::behavior_type typed_calculator() {
  return {
    [](plus_atom, int a, int b) {
      return std::make_tuple(result_atom::value, a + b);
    },
    [](minus_atom, int a, int b) {
      return std::make_tuple(result_atom::value, a - b);
    }
  };
}

// tests a calculator instance
template <class Handle>
void tester(event_based_actor* self, const Handle& testee, int x, int y) {
  self->link_to(testee);
  // will be invoked if we receive an unexpected response message
  self->on_sync_failure([=] {
    aout(self) << "AUT (actor under test) failed" << endl;
    self->quit(exit_reason::user_shutdown);
  });
  // first test: 2 + 1 = 3
  self->sync_send(testee, plus_atom::value, x, y).then(
    [=](result_atom, int res1) {
      aout(self) << x << " + " << y << " = " << res1 << endl;
      self->sync_send(testee, minus_atom::value, x, y).then(
        [=](result_atom, int res2) {
          // both tests succeeded
        aout(self) << x << " - " << y << " = " << res2 << endl;
          self->quit(exit_reason::user_shutdown);
        }
      );
    }
  );
}

void test_calculators() {
  scoped_actor self;
  aout(self) << "blocking actor:" << endl;
  self->spawn(tester<actor>, spawn<blocking_api>(blocking_calculator), 1, 2);
  self->await_all_other_actors_done();
  aout(self) << "event-based actor:" << endl;
  self->spawn(tester<actor>, spawn(calculator), 3, 4);
  self->await_all_other_actors_done();
  aout(self) << "typed actor:" << endl;
  self->spawn(tester<calculator_actor>, spawn_typed(typed_calculator), 5, 6);
  self->await_all_other_actors_done();
}

int main() {
  test_calculators();
  shutdown();
}
{'fraction_non_alphanumeric': 0.2056408425562299, 'fraction_numerical': 0.004462691895751518, 'mean_word_length': 3.4967897271268056, 'pattern_counts': {'":': 0, '<': 105, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6069107', 'n_tokens_mistral': 1877, 'n_tokens_neox': 1811, 'n_words': 435}