text:
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// Name        :
// Author      : Avi
// Revision    : $Revision: #16 $
//
// Copyright 2009-2020 ECMWF.
// This software is licensed under the terms of the Apache Licence version 2.0
// which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
// In applying this licence, ECMWF does not waive the privileges and immunities
// granted to it by virtue of its status as an intergovernmental organisation
// nor does it submit to any jurisdiction.
//
// Description :
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8

#include <stdexcept>
#include <boost/test/unit_test.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/date_time/posix_time/time_formatters.hpp>  // requires boost date and time lib

#include "RepeatAttr.hpp"
#include "Cal.hpp"

using namespace std;
using namespace boost::gregorian;
using namespace boost::posix_time;

BOOST_AUTO_TEST_SUITE( ANattrTestSuite )

BOOST_AUTO_TEST_CASE( test_repeat_invariants )
{
   cout << "ANattr:: ...test_repeat_invariants\n";

   std::vector<std::string> stringList; stringList.reserve(3);
   stringList.emplace_back("a");
   stringList.emplace_back("b");
   stringList.emplace_back("c");

   // Test the invariant that Non empty repeat must have a name
   {
      Repeat empty;
      Repeat empty2;
      BOOST_CHECK_MESSAGE(empty.empty(),"Construction");
      BOOST_CHECK_MESSAGE(empty.name().empty(),"Construction");
      BOOST_CHECK_MESSAGE(empty == empty2,"Equality failed");
   }
   {
      //Repeat rep2(RepeatDateList("YMD",{20090916,20090916}));
      Repeat rep(RepeatDateList("YMD",{20190929,20190131}));
      BOOST_CHECK_MESSAGE(!rep.empty()," Repeat should not be empty");
      BOOST_CHECK_MESSAGE(!rep.name().empty(),"name should not be empty");
      BOOST_CHECK_MESSAGE(rep.name() == "YMD","name not as expected");
      BOOST_CHECK_MESSAGE(rep.start() == 20190929,"Start should be 20190929");
      BOOST_CHECK_MESSAGE(rep.end() == 20190131,"end should be 20190131");
      BOOST_CHECK_MESSAGE(rep.step() == 1,"step should be 1");
      BOOST_CHECK_MESSAGE(rep.value() == 20190929,"value should be 20190929");
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20190929,"last_valid_value should be 20190929");
      BOOST_CHECK_MESSAGE(rep.valueAsString() == "20190929","not as expected");
      BOOST_CHECK_MESSAGE(rep.next_value_as_string() == "20190131","not as expected");
      BOOST_CHECK_MESSAGE(rep.prev_value_as_string() == "20190929","not as expected");
      BOOST_CHECK_MESSAGE(rep.last_valid_value_minus(1) == 20190928,"expected 20190928 but found " << rep.last_valid_value_minus(1));
      BOOST_CHECK_MESSAGE(rep.last_valid_value_plus(1) == 20190930,"expected 20190930 but found " << rep.last_valid_value_minus(1));
      BOOST_CHECK_MESSAGE(rep.last_valid_value_plus(2) == 20191001,"expected 20191001 but found " << rep.last_valid_value_minus(1));

      Repeat cloned = Repeat(rep);
      BOOST_CHECK_MESSAGE(cloned == rep,"Equality failed");
      BOOST_CHECK_MESSAGE(cloned.name() == "YMD","not as expected");
      BOOST_CHECK_MESSAGE(cloned.start() == 20190929,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.end() == 20190131,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.step() == 1,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.value() == 20190929,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.valueAsString() == "20190929","not as expected");
      BOOST_CHECK_MESSAGE(cloned.last_valid_value() == 20190929,"last_valid_value should be 20190929");
      BOOST_CHECK_MESSAGE(cloned.next_value_as_string() == "20190131","not as expected");
      BOOST_CHECK_MESSAGE(cloned.prev_value_as_string() == "20190929","not as expected");

      RepeatDateList empty;
      BOOST_CHECK_MESSAGE(empty.start() == 0,"Start should be 0");
      BOOST_CHECK_MESSAGE(empty.end() == 0,"end should be 0");
      BOOST_CHECK_MESSAGE(empty.step() == 1,"step should be 1");
      BOOST_CHECK_MESSAGE(empty.value() == 0,"delta should be 0");
      BOOST_CHECK_MESSAGE(empty.name().empty(),"name should be empty");
      BOOST_CHECK_MESSAGE(empty.name() == "","name not as expected");
      BOOST_CHECK_MESSAGE(empty.valueAsString() == "0","expected 0 but found " << empty.valueAsString());
      BOOST_CHECK_MESSAGE(empty.next_value_as_string() == "0","expected 0 but found " << empty.next_value_as_string());
      BOOST_CHECK_MESSAGE(empty.prev_value_as_string() == "0","expected 0 but found " << empty.prev_value_as_string());
   }
   {
      Repeat rep(RepeatDateList("YMD",{20190929,20190131}));
      BOOST_CHECK_MESSAGE(rep.start() == 20190929,"Start should be 20190929");
      BOOST_CHECK_MESSAGE(rep.end() ==  20190131,"end should be  20190131");
      BOOST_CHECK_MESSAGE(rep.step() == 1,"step should be 1");
      BOOST_CHECK_MESSAGE(rep.value() == 20190929,"value should be 20190929");
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20190929,"last valid value should be 20190929");
      rep.increment();
      BOOST_CHECK_MESSAGE(rep.valid(),"RepeatDateList should be valid");
      BOOST_CHECK_MESSAGE(rep.value() == 20190131 ,"value should be 20190131 ");
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20190131,"last_valid_value should be 20190131 ");
      rep.increment();
      BOOST_CHECK_MESSAGE(!rep.valid(),"RepeatDateList should not be valid");
      BOOST_CHECK_MESSAGE(rep.value() == 0 ,"expected 0 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20190131,"expected 20190131 but found " << rep.last_valid_value());
   }

   ////////////////////////////////////////////////////////////////////////////
   {
      Repeat rep(RepeatDate("YMD",20090916,20090930,1));
      BOOST_CHECK_MESSAGE(!rep.empty()," Repeat should not be empty");
      BOOST_CHECK_MESSAGE(!rep.name().empty(),"name should not be empty");
      BOOST_CHECK_MESSAGE(rep.name() == "YMD","name not as expected");
      BOOST_CHECK_MESSAGE(rep.start() == 20090916,"Start should be 20090916");
      BOOST_CHECK_MESSAGE(rep.end() == 20090930,"end should be 20090930");
      BOOST_CHECK_MESSAGE(rep.step() == 1,"step should be 1");
      BOOST_CHECK_MESSAGE(rep.value() == 20090916,"value should be 20090916");
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20090916,"last_valid_value should be 20090916");
      BOOST_CHECK_MESSAGE(rep.valueAsString() == "20090916","not as expected");
      BOOST_CHECK_MESSAGE(rep.next_value_as_string() == "20090917","not as expected");
      BOOST_CHECK_MESSAGE(rep.prev_value_as_string() == "20090916","not as expected");

      Repeat cloned = Repeat(rep);
      BOOST_CHECK_MESSAGE(cloned == rep,"Equality failed");
      BOOST_CHECK_MESSAGE(cloned.name() == "YMD","not as expected");
      BOOST_CHECK_MESSAGE(cloned.start() == 20090916,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.end() == 20090930,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.step() == 1,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.value() == 20090916,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.valueAsString() == "20090916","not as expected");
      BOOST_CHECK_MESSAGE(cloned.last_valid_value() == 20090916,"last_valid_value should be 20090916");
      BOOST_CHECK_MESSAGE(cloned.next_value_as_string() == "20090917","not as expected");
      BOOST_CHECK_MESSAGE(cloned.prev_value_as_string() == "20090916","not as expected");

      RepeatDate empty;
      BOOST_CHECK_MESSAGE(empty.start() == 0,"Start should be 0");
      BOOST_CHECK_MESSAGE(empty.end() == 0,"end should be 0");
      BOOST_CHECK_MESSAGE(empty.step() == 0,"step should be 0");
      BOOST_CHECK_MESSAGE(empty.value() == 0,"delta should be 0");
      BOOST_CHECK_MESSAGE(empty.name().empty(),"name should be empty");
      BOOST_CHECK_MESSAGE(empty.name() == "","name not as expected");
      BOOST_CHECK_MESSAGE(empty.valueAsString() == "0","expected 0 but found " << empty.valueAsString());
      BOOST_CHECK_MESSAGE(empty.next_value_as_string() == "0","expected 0 but found " << empty.next_value_as_string());
      BOOST_CHECK_MESSAGE(empty.prev_value_as_string() == "0","expected 0 but found " << empty.prev_value_as_string());
   }
   {
      Repeat rep(RepeatDate("YMD",20090930,20090916,-1));
      BOOST_CHECK_MESSAGE(!rep.empty()," Repeat should not be empty");
      BOOST_CHECK_MESSAGE(!rep.name().empty(),"name should not be empty");
      BOOST_CHECK_MESSAGE(rep.name() == "YMD","name not as expected");
      BOOST_CHECK_MESSAGE(rep.start() == 20090930,"Start should be 20090930");
      BOOST_CHECK_MESSAGE(rep.end() == 20090916,"end should be 20090916");
      BOOST_CHECK_MESSAGE(rep.step() == -1,"step should be -1");
      BOOST_CHECK_MESSAGE(rep.value() == 20090930,"value should be 20090930");
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20090930,"last_valid_value should be 20090930");
      BOOST_CHECK_MESSAGE(rep.valueAsString() == "20090930","not as expected");
      BOOST_CHECK_MESSAGE(rep.next_value_as_string() == "20090929","expected 20090929 but found " << rep.next_value_as_string());
      BOOST_CHECK_MESSAGE(rep.prev_value_as_string() == "20090930","expected 20090930 but found " << rep.prev_value_as_string());

      Repeat cloned = Repeat(rep);
      BOOST_CHECK_MESSAGE(cloned == rep,"Equality failed");
      BOOST_CHECK_MESSAGE(cloned.name() == "YMD","not as expected");
      BOOST_CHECK_MESSAGE(cloned.start() == 20090930,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.end() == 20090916,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.step() == -1,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.value() == 20090930,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.valueAsString() == "20090930","not as expected");
      BOOST_CHECK_MESSAGE(cloned.last_valid_value() == 20090930,"last_valid_value should be 20090930");
   }
   {
      Repeat rep(RepeatDate("YMD",20090916,20090916,1));
      BOOST_CHECK_MESSAGE(rep.start() == 20090916,"Start should be 20090916");
      BOOST_CHECK_MESSAGE(rep.end() == 20090916,"end should be 20090916");
      BOOST_CHECK_MESSAGE(rep.step() == 1,"step should be 1");
      BOOST_CHECK_MESSAGE(rep.value() == 20090916,"value should be 20090916");
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20090916,"delta should be 20090916");
      rep.increment();
      BOOST_CHECK_MESSAGE(!rep.valid(),"RepeatDate should not be valid");
      BOOST_CHECK_MESSAGE(rep.value() == 20090917,"value should be 20090917");
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20090916,"last_valid_value should be 20090916");
   }
   {
      Repeat rep(RepeatDate("YMD",20090916,20090916,-1));
      BOOST_CHECK_MESSAGE(rep.start() == 20090916,"Start should be 20090916");
      BOOST_CHECK_MESSAGE(rep.end() == 20090916,"end should be 20090916");
      BOOST_CHECK_MESSAGE(rep.step() == -1,"step should be -1");
      BOOST_CHECK_MESSAGE(rep.value() == 20090916,"value should be 20090916");
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20090916,"last_valid_value should be 20090916");
      rep.increment();
      BOOST_CHECK_MESSAGE(!rep.valid(),"RepeatDate should not be valid");
      BOOST_CHECK_MESSAGE(rep.value() == 20090915,"value should be 20090915");
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20090916,"last_valid_value should be 20090916");
   }

   {
      Repeat rep(RepeatEnumerated("AEnum",stringList));
      BOOST_CHECK_MESSAGE(!rep.empty()," Repeat should not be empty");
      BOOST_CHECK_MESSAGE(!rep.name().empty(),"name should not be empty");
      BOOST_CHECK_MESSAGE(rep.name() == "AEnum","name not as expected");
      BOOST_CHECK_MESSAGE(rep.valueAsString() == "a","not as expected");
      BOOST_CHECK_MESSAGE(rep.next_value_as_string() == "b","not as expected");
      BOOST_CHECK_MESSAGE(rep.prev_value_as_string() == "a","not as expected");

      Repeat cloned = Repeat(rep);
      BOOST_CHECK_MESSAGE(cloned == rep,"Equality failed");
      BOOST_CHECK_MESSAGE(cloned.name() == "AEnum","not as expected");
      BOOST_CHECK_MESSAGE(cloned.start() == 0,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.step() == 1,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.value() == 0,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.valueAsString() == "a","not as expected");
      BOOST_CHECK_MESSAGE(cloned.next_value_as_string() == "b","not as expected");
      BOOST_CHECK_MESSAGE(cloned.prev_value_as_string() == "a","not as expected");

      RepeatEnumerated empty;
      BOOST_CHECK_MESSAGE(empty.start() == 0,"Start should be 0");
      BOOST_CHECK_MESSAGE(empty.end() == 0,"end should be 0");
      BOOST_CHECK_MESSAGE(empty.step() == 1,"default step should be 1");
      BOOST_CHECK_MESSAGE(empty.value() == 0,"delta should be 0");
      BOOST_CHECK_MESSAGE(empty.name().empty(),"name should be empty");
      BOOST_CHECK_MESSAGE(empty.name() == "","name not as expected");
      BOOST_CHECK_MESSAGE(empty.valueAsString() == "","not as expected");
      BOOST_CHECK_MESSAGE(empty.next_value_as_string() == "","not as expected");
      BOOST_CHECK_MESSAGE(empty.prev_value_as_string() == "","not as expected");
   }
   {
      Repeat rep(RepeatInteger("rep",0,100,1));
      BOOST_CHECK_MESSAGE(!rep.empty()," Repeat should not be empty");
      BOOST_CHECK_MESSAGE(!rep.name().empty(),"name should not be empty");
      BOOST_CHECK_MESSAGE(rep.name() == "rep","name not as expected");
      BOOST_CHECK_MESSAGE(rep.valueAsString() == "0","not as expected");
      BOOST_CHECK_MESSAGE(rep.next_value_as_string() == "1","not as expected");
      BOOST_CHECK_MESSAGE(rep.prev_value_as_string() == "0","not as expected");

      Repeat cloned = Repeat(rep);
      BOOST_CHECK_MESSAGE(cloned == rep,"Equality failed");
      BOOST_CHECK_MESSAGE(cloned.name() == "rep","not as expected");
      BOOST_CHECK_MESSAGE(cloned.start() == 0,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.end() == 100,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.step() == 1,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.value() == 0,"not as expected");
      BOOST_CHECK_MESSAGE(cloned.valueAsString() == "0","not as expected");
      BOOST_CHECK_MESSAGE(cloned.next_value_as_string() == "1","not as expected");
      BOOST_CHECK_MESSAGE(cloned.prev_value_as_string() == "0","not as expected");

      RepeatInteger empty;
      BOOST_CHECK_MESSAGE(empty.start() == 0,"Start should be 0");
      BOOST_CHECK_MESSAGE(empty.end() == 0,"end should be 0");
      BOOST_CHECK_MESSAGE(empty.step() == 0,"default step should be 0 but found" <<  empty.step());
      BOOST_CHECK_MESSAGE(empty.value() == 0,"delta should be 0");
      BOOST_CHECK_MESSAGE(empty.name().empty(),"name should be empty");
      BOOST_CHECK_MESSAGE(empty.name() == "","name not as expected");
      BOOST_CHECK_MESSAGE(empty.valueAsString() == "0","not as expected");
      BOOST_CHECK_MESSAGE(empty.next_value_as_string() == "0","not as expected");
      BOOST_CHECK_MESSAGE(empty.prev_value_as_string() == "0","not as expected");
   }
   {
      Repeat rep(RepeatDay(2));
      BOOST_CHECK_MESSAGE(!rep.empty()," Repeat should not be empty");
      BOOST_CHECK_MESSAGE(!rep.name().empty(),"name should not be empty");
      BOOST_CHECK_MESSAGE(rep.name() == "day","name not as expected");

      Repeat cloned = Repeat(rep);
      BOOST_CHECK_MESSAGE(cloned == rep,"Equality failed");
      BOOST_CHECK_MESSAGE(cloned.name() == "day","name not as expected");
      BOOST_CHECK_MESSAGE(cloned.step() == 2,"step not as expected");

      RepeatDay empty;
      BOOST_CHECK_MESSAGE(empty.start() == 0,"Start should be 0");
      BOOST_CHECK_MESSAGE(empty.end() == 0,"end should be 0");
      BOOST_CHECK_MESSAGE(empty.step() == 1,"default step should be 0 but found " <<  empty.step());
      BOOST_CHECK_MESSAGE(empty.value() == 1,"value should be 0 but found " << empty.value());
      BOOST_CHECK_MESSAGE(empty.name() == "day","name not as expected");
      BOOST_CHECK_MESSAGE(empty.valueAsString() == "","not as expected");
      BOOST_CHECK_MESSAGE(empty.next_value_as_string() == "","not as expected");
      BOOST_CHECK_MESSAGE(empty.prev_value_as_string() == "","not as expected");
   }
}

BOOST_AUTO_TEST_CASE( test_repeat )
{
	cout << "ANattr:: ...test_repeat \n";

	std::vector<std::string> stringList; stringList.reserve(3);
	stringList.emplace_back("a");
	stringList.emplace_back("b");
	stringList.emplace_back("c");

	Repeat empty;
	Repeat empty2;

	{
 		Repeat l1(RepeatDate("YMD",20090916,20090930,1));
		Repeat l2(RepeatDate("YMD",20090916,20090930,1));
 		BOOST_CHECK_MESSAGE(!l1.empty(),"Construction failed");
 		BOOST_CHECK_MESSAGE(!l2.empty(),"Construction failed");
 		BOOST_CHECK_MESSAGE(l1 == l2,"Equality failed");
 		BOOST_CHECK_MESSAGE(!(l1 == empty),"Equality failed");

      Repeat l1a(RepeatDate("YMD",20090930,20090916,-1));
      Repeat l2a(RepeatDate("YMD",20090930,20090916,-1));
      BOOST_CHECK_MESSAGE(!l1a.empty(),"Construction failed");
      BOOST_CHECK_MESSAGE(!l2a.empty(),"Construction failed");
      BOOST_CHECK_MESSAGE(l1a == l2a,"Equality failed");
      BOOST_CHECK_MESSAGE(!(l1a == empty),"Equality failed");

 		Repeat la(RepeatEnumerated("AEnum",stringList));
		Repeat lb(RepeatEnumerated("AEnum",stringList));
		BOOST_CHECK_MESSAGE(!la.empty(),"Construction failed");
 		BOOST_CHECK_MESSAGE(!lb.empty(),"Construction failed");
 		BOOST_CHECK_MESSAGE(la == lb,"Equality failed");
 		BOOST_CHECK_MESSAGE(!(la == empty),"Equality failed");

 		Repeat lc(RepeatString("RepeatString",stringList));
		Repeat ld(RepeatString("RepeatString",stringList));
		BOOST_CHECK_MESSAGE(!lc.empty(),"Construction failed");
 		BOOST_CHECK_MESSAGE(!ld.empty(),"Construction failed");
 		BOOST_CHECK_MESSAGE(lc == lc,"Equality failed");
 		BOOST_CHECK_MESSAGE(!(lc == empty),"Equality failed");

 		Repeat le(RepeatInteger("rep",0,100,1));
		Repeat lf(RepeatInteger("rep",0,100,1));
		BOOST_CHECK_MESSAGE(!le.empty(),"Construction failed");
 		BOOST_CHECK_MESSAGE(!lf.empty(),"Construction failed");
 		BOOST_CHECK_MESSAGE(le == lf,"Equality failed");
 		BOOST_CHECK_MESSAGE(!(le == empty),"Equality failed");

		l1.clear();
 		l2.clear();
 		la.clear();
 		lb.clear();
 		lc.clear();
 		ld.clear();
 		le.clear();
 		lf.clear();
 		BOOST_CHECK_MESSAGE(l1 == empty,"Clear failed");
 		BOOST_CHECK_MESSAGE(l2 == empty,"Clear failed");
 		BOOST_CHECK_MESSAGE(la == empty,"Clear failed");
 		BOOST_CHECK_MESSAGE(lb == empty,"Clear failed");
 		BOOST_CHECK_MESSAGE(lc == empty,"Clear failed");
 		BOOST_CHECK_MESSAGE(ld == empty,"Clear failed");
 		BOOST_CHECK_MESSAGE(le == empty,"Clear failed");
 		BOOST_CHECK_MESSAGE(lf == empty,"Clear failed");
	}

	{
 		Repeat l1(RepeatDate("YMD",20090916,20090930,1));
		Repeat l2;
		l2 = l1;
 		BOOST_CHECK_MESSAGE(l1 == l2,"Assignment failed");

 		l2 = empty;
 		BOOST_CHECK_MESSAGE(l2 == empty,"Assignment failed");

 		Repeat la(RepeatEnumerated("AEnum",stringList));
 		Repeat lb;
 		lb = la;
 		BOOST_CHECK_MESSAGE(la == lb,"Assignment failed");

 		Repeat lc(RepeatString("RepeatString",stringList));
 		Repeat ld;
 		ld = lc;
 		BOOST_CHECK_MESSAGE(lc == ld,"Assignment failed");

 		Repeat le(RepeatInteger("rep",0,100,1));
		Repeat lf;
		lf = le;
 		BOOST_CHECK_MESSAGE(le == lf,"Assignment failed");
 	}

	{
		Repeat l1(RepeatDate("YMD",20090916,20090930,1));

		Repeat l2 = l1;
  		BOOST_CHECK_MESSAGE(l1 == l2,"Copy construction failed");

 		Repeat la(RepeatEnumerated("AEnum",stringList));
 		Repeat lb = la;
 		BOOST_CHECK_MESSAGE(la == lb,"Copy construction failed");

 		Repeat lc(RepeatString("RepeatString",stringList));
 		Repeat ld = lc;
 		BOOST_CHECK_MESSAGE(lc == ld,"Copy construction failed");

 		Repeat le(RepeatInteger("rep",0,100,1));
		Repeat lf = le;
 		BOOST_CHECK_MESSAGE(le == lf,"Copy construction failed");

		Repeat empty_1( empty );
 		BOOST_CHECK_MESSAGE(empty_1 == empty,"Copy construction failed");
 	}

	{
 		BOOST_CHECK_MESSAGE(empty.name() == string()," empty  failed");
 		BOOST_CHECK_MESSAGE(empty.valid() == false," empty  failed");
 		BOOST_CHECK_MESSAGE(empty.value() == 0," empty  failed");
 		empty.setToLastValue();
 		BOOST_CHECK_MESSAGE(empty.valueAsString() == string()," empty  failed");
 		empty.reset();
 		empty.increment();
 		empty.change("fred");
 		BOOST_CHECK_MESSAGE(empty.valueAsString() == string()," empty  failed");
 		empty.changeValue(10);
 		BOOST_CHECK_MESSAGE(empty.valueAsString() == string()," empty  failed");
 		BOOST_CHECK_MESSAGE(empty.isInfinite() == false," empty  failed");
 		BOOST_CHECK_MESSAGE(empty.toString() == string()," empty  failed");
 		BOOST_CHECK_MESSAGE(empty.state_change_no() ==0," empty  failed");
	}

	{
 		Repeat day(RepeatDay(2));
 		Repeat day2 = day;
      BOOST_CHECK_MESSAGE(day == day2,"Copy construction failed");

		day.reset();
 		BOOST_CHECK_MESSAGE(day.valid(),"Should return true after reset");
	}
}

BOOST_AUTO_TEST_CASE( test_repeat_move_semantics )
{
   cout << "ANattr:: ...test_repeat_move_semantics\n";

   std::vector<std::string> stringList{ "a", "b", "c" };
   {
      Repeat x;
      BOOST_CHECK_MESSAGE(x.empty(),"Construction failed");

      Repeat l1(RepeatDate("YMD",20090916,20090930,1));
      x = l1;
      BOOST_CHECK_MESSAGE(!x.empty(),"copy assignment failed");
      BOOST_CHECK_MESSAGE(x == l1,"Equality failed, after copy assignment");
      x = std::move(l1);
      BOOST_CHECK_MESSAGE(!x.empty(),"move assignment failed");
      BOOST_CHECK_MESSAGE(l1.empty(),"move assignment failed");
   }
   {
      Repeat r1(RepeatDate("YMD",20090916,20090930,1));
      Repeat r2 = Repeat(r1); //copy construction
      BOOST_CHECK_MESSAGE(!r1.empty()," copy construction failed");
      BOOST_CHECK_MESSAGE(!r2.empty()," copy construction failed");
      BOOST_CHECK_MESSAGE(r1 == r2,"Equality failed, after copy construction");

      Repeat r3 = Repeat(std::move(r1)); // move construction
      BOOST_CHECK_MESSAGE(r1.empty(),"move construction failed");
      BOOST_CHECK_MESSAGE(r2 == r3,"Equality failed, after move construction");
   }
}

BOOST_AUTO_TEST_CASE( test_repeat_last_value )
{
   cout << "ANattr:: ...test_repeat_last_value \n";

   {
      Repeat rep(RepeatDate("YMD",20090916,20090930,1));
      rep.update_repeat_genvar();
      const Variable& gen_var = rep.find_gen_variable("YMD_JULIAN");
      int old_value = gen_var.value();
      rep.setToLastValue();
      int new_value = gen_var.value();

      BOOST_CHECK_MESSAGE(rep.value() == 20090930,"Set to last value did not work, expected 20090930 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.valueAsString() == "20090930","Set to last value did not work, expected '20090930' but found " << rep.valueAsString());
      BOOST_CHECK_MESSAGE(rep.next_value_as_string() == "20090930","next_value_as_string() did not work, expected 20090930 but found " << rep.next_value_as_string());
      BOOST_CHECK_MESSAGE(rep.prev_value_as_string() == "20090929","prev_value_as_string() did not work, expected 20090929 but found " << rep.prev_value_as_string());
      BOOST_CHECK_MESSAGE(old_value != new_value ,"Expected to update the generated variables ");
   }
   {
      Repeat rep(RepeatDate("YMD",20090930,20090916,-1));
      rep.setToLastValue();
      BOOST_CHECK_MESSAGE(rep.value() == 20090916,"Set to last value did not work, expected 20090916 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.valueAsString() == "20090916","Set to last value did not work, expected '20090916' but found " << rep.valueAsString());
      BOOST_CHECK_MESSAGE(rep.next_value_as_string() == "20090916","next_value_as_string() did not work, expected 20090916 but found " << rep.next_value_as_string());
      BOOST_CHECK_MESSAGE(rep.prev_value_as_string() == "20090917","prev_value_as_string() did not work, expected 20090917 but found " << rep.prev_value_as_string());
   }

   std::vector<std::string> stringList; stringList.reserve(3);
   stringList.emplace_back("a");
   stringList.emplace_back("b");
   stringList.emplace_back("c");
   {
      Repeat rep(RepeatEnumerated("AEnum",stringList));
      rep.setToLastValue();
      BOOST_CHECK_MESSAGE(rep.value() == 2,"Set to last value did not work, expected 2 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.valueAsString() == "c","Set to last value did not work, expected 'c' but found " << rep.valueAsString());
      BOOST_CHECK_MESSAGE(rep.value_as_string(0) == "a"," Expected 'a' but found " << rep.value_as_string(0));
      BOOST_CHECK_MESSAGE(rep.value_as_string(1) == "b"," Expected 'b' but found " << rep.value_as_string(1));
      BOOST_CHECK_MESSAGE(rep.value_as_string(2) == "c"," Expected 'c' but found " << rep.value_as_string(2));
      BOOST_CHECK_MESSAGE(rep.next_value_as_string() == "c","next_value_as_string() did not work, expected c but found " << rep.next_value_as_string());
      BOOST_CHECK_MESSAGE(rep.prev_value_as_string() == "b","prev_value_as_string() did not work, expected b but found " << rep.prev_value_as_string());
   }
   {
      Repeat rep(RepeatString("Str",stringList));
      rep.setToLastValue();
      BOOST_CHECK_MESSAGE(rep.value() == 2,"Set to last value did not work, expected 2 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.valueAsString() == "c","Set to last value did not work, expected 'c' but found " << rep.valueAsString());
      BOOST_CHECK_MESSAGE(rep.value_as_string(0) == "a"," Expected 'a' but found " << rep.value_as_string(0));
      BOOST_CHECK_MESSAGE(rep.value_as_string(1) == "b"," Expected 'b' but found " << rep.value_as_string(1));
      BOOST_CHECK_MESSAGE(rep.value_as_string(2) == "c"," Expected 'c' but found " << rep.value_as_string(2));
      BOOST_CHECK_MESSAGE(rep.next_value_as_string() == "c","next_value_as_string() did not work, expected c but found " << rep.next_value_as_string());
      BOOST_CHECK_MESSAGE(rep.prev_value_as_string() == "b","prev_value_as_string() did not work, expected b but found " << rep.prev_value_as_string());
   }

   {
      Repeat rep(RepeatInteger("integer",0,10,1));
      rep.setToLastValue();
      BOOST_CHECK_MESSAGE(rep.value() == 10,"Set to last value did not work, expected 10 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.value_as_string(0) == "0"," Expected '0' but found " << rep.value_as_string(0));
      BOOST_CHECK_MESSAGE(rep.value_as_string(1) == "1"," Expected '1' but found " << rep.value_as_string(1));
      BOOST_CHECK_MESSAGE(rep.value_as_string(2) == "2"," Expected '2' but found " << rep.value_as_string(2));
      BOOST_CHECK_MESSAGE(rep.next_value_as_string() == "10","next_value_as_string() did not work, expected 10 but found " << rep.next_value_as_string());
      BOOST_CHECK_MESSAGE(rep.prev_value_as_string() == "9","prev_value_as_string() did not work, expected 9 but found " << rep.prev_value_as_string());
   }
   {
      Repeat rep(RepeatInteger("integer",10,0,-1));
      rep.setToLastValue();
      BOOST_CHECK_MESSAGE(rep.value() == 0,"Set to last value did not work, expected 0 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.value_as_string(0) == "0"," Expected '0' but found " << rep.value_as_string(0));
      BOOST_CHECK_MESSAGE(rep.value_as_string(1) == "1"," Expected '1' but found " << rep.value_as_string(1));
      BOOST_CHECK_MESSAGE(rep.value_as_string(2) == "2"," Expected '2' but found " << rep.value_as_string(2));
      BOOST_CHECK_MESSAGE(rep.next_value_as_string() == "0","next_value_as_string() did not work, expected 0 but found " << rep.next_value_as_string());
      BOOST_CHECK_MESSAGE(rep.prev_value_as_string() == "1","prev_value_as_string() did not work, expected 1 but found " << rep.prev_value_as_string());
   }
}

BOOST_AUTO_TEST_CASE( test_repeat_enumerated_as_string_integers )
{
   cout << "ANattr:: ...test_repeat_enumerated_as_string_integers\n";

   std::vector<std::string> stringList; stringList.reserve(3);
   stringList.emplace_back("20130101");
   stringList.emplace_back("20130102");
   stringList.emplace_back("20130103");
   {
      Repeat rep(RepeatEnumerated("AEnum",stringList));
      // Note: valueAsString should return string at the last valid index

      BOOST_CHECK_MESSAGE(rep.valid(),"Expected rep to be valid");
      BOOST_CHECK_MESSAGE(rep.value() == 20130101," Expected 20130101 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20130101," Expected 20130101 but found " << rep.last_valid_value());
      BOOST_CHECK_MESSAGE(rep.valueAsString() == "20130101"," Expected '20130101' but found " << rep.valueAsString());
      BOOST_CHECK_MESSAGE(rep.value_as_string(0) == "20130101"," Expected '20130101' but found " << rep.value_as_string(0));
      BOOST_CHECK_MESSAGE(rep.next_value_as_string() == "20130102"," Expected '20130102' but found " << rep.next_value_as_string());
      BOOST_CHECK_MESSAGE(rep.prev_value_as_string() == "20130101"," Expected '20130101' but found " << rep.prev_value_as_string());

      rep.increment();
      BOOST_CHECK_MESSAGE(rep.valid(),"Expected rep to be valid");
      BOOST_CHECK_MESSAGE(rep.value() == 20130102," Expected 20130102 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20130102," Expected 20130102 but found " << rep.last_valid_value());
      BOOST_CHECK_MESSAGE(rep.valueAsString() == "20130102"," Expected '20130102' but found " << rep.valueAsString());
      BOOST_CHECK_MESSAGE(rep.value_as_string(1) == "20130102"," Expected '20130102' but found " << rep.value_as_string(1));
      BOOST_CHECK_MESSAGE(rep.next_value_as_string() == "20130103"," Expected '20130103' but found " << rep.next_value_as_string());
      BOOST_CHECK_MESSAGE(rep.prev_value_as_string() == "20130101"," Expected '20130101' but found " << rep.prev_value_as_string());

      rep.increment();
      BOOST_CHECK_MESSAGE(rep.value() == 20130103," Expected 20130103 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20130103," Expected 20130103 but found " << rep.last_valid_value());
      BOOST_CHECK_MESSAGE(rep.valueAsString() == "20130103"," Expected '20130103' but found " << rep.valueAsString());
      BOOST_CHECK_MESSAGE(rep.value_as_string(2) == "20130103"," Expected '20130103' but found " << rep.value_as_string(2));
      BOOST_CHECK_MESSAGE(rep.next_value_as_string() == "20130103"," Expected '20130103' but found " << rep.next_value_as_string());
      BOOST_CHECK_MESSAGE(rep.prev_value_as_string() == "20130102"," Expected '20130102' but found " << rep.prev_value_as_string());

      rep.increment();
      BOOST_CHECK_MESSAGE(!rep.valid(),"Expected rep to be in-valid");
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20130103," Expected 20130103 but found " << rep.last_valid_value());
      BOOST_CHECK_MESSAGE(rep.valueAsString() == "20130103"," Expected '20130103' but found " << rep.valueAsString());

      rep.increment();
      BOOST_CHECK_MESSAGE(!rep.valid(),"Expected rep to be in-valid");
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20130103," Expected 20130103 but found " << rep.last_valid_value());
      BOOST_CHECK_MESSAGE(rep.valueAsString() == "20130103"," Expected '20130103' but found " << rep.valueAsString());
   }
}

BOOST_AUTO_TEST_CASE( test_repeat_increment )
{
   cout << "ANattr:: ...test_repeat_increment \n";

   {
      Repeat rep(RepeatDate("YMD",20090916,20090920,1));
      rep.update_repeat_genvar();
      const Variable& gen_var = rep.find_gen_variable("YMD_JULIAN");
      const Variable& gen_var2 = rep.find_gen_variable("YMD_DOW");
      int old_value = gen_var.value();
      int old_value2 = gen_var2.value();

      while( rep.valid()) { rep.increment(); }

      BOOST_CHECK_MESSAGE(rep.value() == 20090921,"expected 20090921 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20090920,"expected 20090920 but found " << rep.last_valid_value());
      BOOST_CHECK_MESSAGE(old_value != gen_var.value(),"Expected generated variables to change on increment");
      BOOST_CHECK_MESSAGE(old_value2 != gen_var2.value(),"Expected generated variables to change on increment");

      rep.reset();
      BOOST_CHECK_MESSAGE(old_value = gen_var.value(),"Expected generated variables to be the same after reset");
      BOOST_CHECK_MESSAGE(old_value2 = gen_var2.value(),"Expected generated variables to be the same after reset");
   }
   {
      Repeat rep(RepeatDate("YMD",20090920,20090916,-1));
      while( rep.valid()) { rep.increment(); }
      BOOST_CHECK_MESSAGE(rep.value() == 20090915,"expected 20090915 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20090916,"expected 20090916 but found " << rep.last_valid_value());
   }

   {
      Repeat rep(RepeatDate("YMD",20150514,20150730,7));
      while( rep.valid()) { rep.increment();
         //cout << "YMD: " << rep.value() << "\n";
      }
      BOOST_CHECK_MESSAGE(rep.value() == 20150806,"expected 20150806 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20150730,"expected 20150730 but found " << rep.last_valid_value());
   }
   {
      Repeat rep(RepeatDate("YMD",20150730,20150514,-7));
      while( rep.valid()) {
          rep.increment();
          //cout << "YMD: " << rep.value() << "\n";
      }
      BOOST_CHECK_MESSAGE(rep.value() == 20150507,"expected 20150507 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20150514,"expected 20150514 but found " << rep.last_valid_value());
   }

   std::vector<std::string> stringList; stringList.reserve(3);
   stringList.emplace_back("a");
   stringList.emplace_back("b");
   stringList.emplace_back("c");
   {
      Repeat rep(RepeatEnumerated("AEnum",stringList));
      while( rep.valid()) { rep.increment(); }
      BOOST_CHECK_MESSAGE(rep.value() == 3," Expected 3 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 2," Expected 2 but found " << rep.last_valid_value());
   }
   {
      Repeat rep(RepeatString("Str",stringList));
      while( rep.valid()) { rep.increment(); }
      BOOST_CHECK_MESSAGE(rep.value() == 3," Expected 3 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 2," Expected 2 but found " << rep.last_valid_value());
   }
   {
      Repeat rep(RepeatInteger("integer",0,10,1));
      while( rep.valid()) { rep.increment(); }
      BOOST_CHECK_MESSAGE(rep.value() == 11," Expected 11 but found " << rep.value());
      BOOST_CHECK_MESSAGE(rep.last_valid_value() == 10," Expected 10 but found " << rep.last_valid_value());
   }
}

BOOST_AUTO_TEST_CASE( test_repeat_date_change_value )
{
   cout << "ANattr:: ...test_repeat_date_change_value \n";
   {
      Repeat rep2(RepeatDate("YMD",20150514,20150730,7));
      Repeat rep(RepeatDate("YMD",20150514,20150730,7));
      BOOST_CHECK_MESSAGE(rep.valid(),"expected valid at start ");

      while( rep.valid() ) {
         rep2.change(boost::lexical_cast<std::string>(rep.value()));
         BOOST_CHECK_MESSAGE(rep.value() == rep2.value(),"expected same value, but found " << rep.value() << "  " << rep2.value());
         rep.increment();
      }
   }
   {
      Repeat rep2(RepeatDate("YMD",20150730,20150514,-7));
      Repeat rep(RepeatDate("YMD",20150730,20150514,-7));
      BOOST_CHECK_MESSAGE(rep.valid(),"expected valid at start ");

      while( rep.valid() ) {
         rep2.change(boost::lexical_cast<std::string>(rep.value()));
         BOOST_CHECK_MESSAGE(rep.value() == rep2.value(),"expected same value, but found " << rep.value() << "  " << rep2.value());
         rep.increment();
      }
   }
}

BOOST_AUTO_TEST_CASE( test_repeat_date_errors )
{
   cout << "ANattr:: ...test_repeat_date_errors \n";

   std::vector<std::string> empty;
   std::vector<std::string> stringList;stringList.emplace_back("a");stringList.emplace_back("b");
   BOOST_REQUIRE_THROW( RepeatEnumerated("",stringList),std::runtime_error); // empty name
   BOOST_REQUIRE_THROW( RepeatEnumerated(" ",stringList),std::runtime_error); // empty name
   BOOST_REQUIRE_THROW( RepeatEnumerated("*",stringList),std::runtime_error); // illegal name
   BOOST_REQUIRE_THROW( RepeatString("",stringList),std::runtime_error);      // empty name
   BOOST_REQUIRE_THROW( RepeatString(" ",stringList),std::runtime_error);     // empty name
   BOOST_REQUIRE_THROW( RepeatString("!£$%^&*()",stringList),std::runtime_error);     // illegal name
   BOOST_REQUIRE_THROW( RepeatEnumerated("AEnum",empty),std::runtime_error); // empty enumerations
   BOOST_REQUIRE_THROW( RepeatString("AEnum",empty),std::runtime_error);     // empty string list

   BOOST_REQUIRE_THROW( RepeatDate("",20090916,20090920,1),std::runtime_error);
   BOOST_REQUIRE_THROW( RepeatDate("YMD",200909161,20090920,1),std::runtime_error); // start > 8
   BOOST_REQUIRE_THROW( RepeatDate("YMD",20090916,200909201,1),std::runtime_error); // end > 8
   BOOST_REQUIRE_THROW( RepeatDate("YMD",20090016,200909201,1),std::runtime_error); // invalid start month
   BOOST_REQUIRE_THROW( RepeatDate("YMD",20090900,20090920,1),std::runtime_error);  // invalid start day
   BOOST_REQUIRE_THROW( RepeatDate("YMD",20090916,20090020,1),std::runtime_error);  // invalid end month
   BOOST_REQUIRE_THROW( RepeatDate("YMD",20090916,20090900,1),std::runtime_error);  // invalid end day
   BOOST_REQUIRE_THROW( RepeatDate("YMD",20090916,20090920,0),std::runtime_error);  // delta cannot be zero

   BOOST_REQUIRE_THROW( RepeatDate("YMD",20090920,20090916,1),std::runtime_error);  //  start day > end day, and delta > 0
   BOOST_REQUIRE_THROW( RepeatDate("YMD",20090916,20090920,-1),std::runtime_error);  //  start day < end day, and delta < 0

   RepeatDate date("YMD",20150514,20150730,7);
   BOOST_REQUIRE_THROW( date.changeValue(20150513),std::runtime_error);   // outside of range
   BOOST_REQUIRE_THROW( date.changeValue(20150731),std::runtime_error);   // outside of range
   BOOST_REQUIRE_THROW( date.changeValue(20150801),std::runtime_error);   // outside of range

   BOOST_REQUIRE_THROW( date.changeValue(20150515),std::runtime_error);   // not a valid step
   BOOST_REQUIRE_THROW( date.changeValue(20150516),std::runtime_error);   // not a valid step
   BOOST_REQUIRE_THROW( date.changeValue(20150517),std::runtime_error);   // not a valid step
   BOOST_REQUIRE_THROW( date.changeValue(20150518),std::runtime_error);   // not a valid step
   BOOST_REQUIRE_THROW( date.changeValue(20150519),std::runtime_error);   // not a valid step
   BOOST_REQUIRE_THROW( date.changeValue(20150520),std::runtime_error);   // not a valid step
   BOOST_REQUIRE_THROW( date.changeValue(20150522),std::runtime_error);   // not a valid step

   RepeatDate date1("YMD",20150730,20150514,-7);
   BOOST_REQUIRE_THROW( date1.changeValue(20150731),std::runtime_error);   // outside of range
   BOOST_REQUIRE_THROW( date1.changeValue(20150813),std::runtime_error);   // outside of range
   BOOST_REQUIRE_THROW( date1.changeValue(20150513),std::runtime_error);   // outside of range
   BOOST_REQUIRE_THROW( date1.changeValue(20150413),std::runtime_error);   // outside of range

   BOOST_REQUIRE_THROW( date.changeValue(20150729),std::runtime_error);    // not a valid step
   BOOST_REQUIRE_THROW( date.changeValue(20150728),std::runtime_error);    // not a valid step
   BOOST_REQUIRE_THROW( date.changeValue(20150515),std::runtime_error);    // not a valid step
}

static void check_date(int start, int end, int delta)
{
   boost::gregorian::date bdate(from_undelimited_string(boost::lexical_cast<std::string>(start)));

   Repeat rep(RepeatDate("YMD",start,end,delta));
   Repeat rep2(RepeatDate("YMD",start,end,delta));
   while (rep.valid()) {

      // xref repeat date with boost date, essentially checking bdate with rep
      string str_value = boost::lexical_cast<std::string>(rep.value());
      boost::gregorian::date date2(from_undelimited_string( str_value ));
      BOOST_CHECK_MESSAGE(bdate == date2 ,"expected same value, but found " << bdate << "  " << date2);

      // check change value
      rep2.change(str_value);
      BOOST_CHECK_MESSAGE(rep.value() == rep2.value(),"expected same value, but found " << rep.value() << "  " << rep2.value());

      // increment repeat and boost date
      rep.increment();
      bdate += days(delta);
   }
}

BOOST_AUTO_TEST_CASE( test_repeat_date_xref_to_boost_date )
{
   cout << "ANattr:: ...test_repeat_date_xref_to_boost_date \n";

   check_date(19800101,20621231,1);
   check_date(19800101,20621231,7);
   check_date(20621231,19800101,-7);
   check_date(20150514,20150730,7);
}

BOOST_AUTO_TEST_CASE( test_repeat_date_generated_variables )
{
   cout << "ANattr:: ...test_repeat_date_generated_variables\n";

    Repeat rep(RepeatDate("YMD",20090916,20090930,1));
    BOOST_CHECK_MESSAGE(!rep.empty()," Repeat should not be empty");
    BOOST_CHECK_MESSAGE(!rep.name().empty(),"name should not be empty");
    BOOST_CHECK_MESSAGE(rep.name() == "YMD","name not as expected");
    BOOST_CHECK_MESSAGE(rep.start() == 20090916,"Start should be 20090916");
    BOOST_CHECK_MESSAGE(rep.end() == 20090930,"end should be 20090930");
    BOOST_CHECK_MESSAGE(rep.step() == 1,"step should be 1");
    BOOST_CHECK_MESSAGE(rep.value() == 20090916,"value should be 20090916");
    BOOST_CHECK_MESSAGE(rep.last_valid_value() == 20090916,"last_valid_value should be 20090916");
    rep.update_repeat_genvar();
    std::vector<Variable> vec;
    rep.gen_variables(vec);
    BOOST_CHECK_MESSAGE(vec.size() == 6,"expected 6 generated variables but found " << vec.size());

    {const Variable& var = rep.find_gen_variable("YMD");
    BOOST_CHECK_MESSAGE(!var.empty(),"Did not find generated variable YMD_YYYY");
    BOOST_CHECK_MESSAGE(var.theValue() == "20090916", "expected year to be 20090916  but found " << var.theValue() );}

    {const Variable& var = rep.find_gen_variable("YMD_YYYY");
    BOOST_CHECK_MESSAGE(!var.empty(),"Did not find generated variable YMD_YYYY");
    BOOST_CHECK_MESSAGE(var.theValue() == "2009", "expected year to be 2009  but found " << var.theValue() );}

    {const Variable& var = rep.find_gen_variable("YMD_MM");
    BOOST_CHECK_MESSAGE(!var.empty(),"Did not find generated variable YMD_MM");
    BOOST_CHECK_MESSAGE(var.theValue() == "9", "expected month to be 9  but found " << var.theValue() );}

    {const Variable& var = rep.find_gen_variable("YMD_DD");
    BOOST_CHECK_MESSAGE(!var.empty(),"Did not find generated variable YMD_DD");
    BOOST_CHECK_MESSAGE(var.theValue() == "16", "expected day of month to be 16 but found " << var.theValue() );}

    {const Variable& var = rep.find_gen_variable("YMD_DOW");
    BOOST_CHECK_MESSAGE(!var.empty(),"Did not find generated variable YMD_DOW");
    BOOST_CHECK_MESSAGE(var.theValue() == "3", "expected day of week to be 3 but found " << var.theValue() );}

    {const Variable& var = rep.find_gen_variable("YMD_JULIAN");
    BOOST_CHECK_MESSAGE(!var.empty(),"Did not find generated variable YMD_JULIAN");
    std::string expected = boost::lexical_cast<std::string>(Cal::date_to_julian(20090916));
    BOOST_CHECK_MESSAGE(var.theValue() == expected, "expected " << expected << " but found " << var.theValue() );}
}

BOOST_AUTO_TEST_CASE( test_repeat_date_generated_variables2 )
{
   cout << "ANattr:: ...test_repeat_date_generated_variables\n";

   int start = 20161231;
   int end = 20170106;
   Repeat rep(RepeatDate("YMD",start,end,1));
   BOOST_CHECK_MESSAGE(!rep.empty()," Repeat should not be empty");
   BOOST_CHECK_MESSAGE(!rep.name().empty(),"name should not be empty");
   BOOST_CHECK_MESSAGE(rep.name() == "YMD","name not as expected");
   BOOST_CHECK_MESSAGE(rep.start() == start ,"Start should be " << start);
   BOOST_CHECK_MESSAGE(rep.end() == end ,"end should be " << end << " but found " << rep.end());
   BOOST_CHECK_MESSAGE(rep.step() == 1,"step should be 1");
   BOOST_CHECK_MESSAGE(rep.value() == start,"value should be " << start << " but found " << rep.value());
   BOOST_CHECK_MESSAGE(rep.last_valid_value() == start,"last_valid_value should be " << start << " but found " << rep.last_valid_value());

   std::vector<std::string> expected_YMD;
   expected_YMD.emplace_back("20161231");
   expected_YMD.emplace_back("20170101");
   expected_YMD.emplace_back("20170102");
   expected_YMD.emplace_back("20170103");
   expected_YMD.emplace_back("20170104");
   expected_YMD.emplace_back("20170105");
   expected_YMD.emplace_back("20170106");

   std::vector<std::string> expected_year;
   expected_year.emplace_back("2016");
   expected_year.emplace_back("2017");
   expected_year.emplace_back("2017");
   expected_year.emplace_back("2017");
   expected_year.emplace_back("2017");
   expected_year.emplace_back("2017");
   expected_year.emplace_back("2017");

   std::vector<std::string> expected_MM;
   expected_MM.emplace_back("12");
   expected_MM.emplace_back("1");
   expected_MM.emplace_back("1");
   expected_MM.emplace_back("1");
   expected_MM.emplace_back("1");
   expected_MM.emplace_back("1");
   expected_MM.emplace_back("1");

   std::vector<std::string> expected_day_of_month;
   expected_day_of_month.emplace_back("31");
   expected_day_of_month.emplace_back("1");
   expected_day_of_month.emplace_back("2");
   expected_day_of_month.emplace_back("3");
   expected_day_of_month.emplace_back("4");
   expected_day_of_month.emplace_back("5");
   expected_day_of_month.emplace_back("6");

   std::vector<std::string> expected_day_of_week;
   expected_day_of_week.emplace_back("6");
   expected_day_of_week.emplace_back("0");
   expected_day_of_week.emplace_back("1");
   expected_day_of_week.emplace_back("2");
   expected_day_of_week.emplace_back("3");
   expected_day_of_week.emplace_back("4");
   expected_day_of_week.emplace_back("5");

   std::vector<std::string> expected_julian;
   expected_julian.push_back(boost::lexical_cast<std::string>(Cal::date_to_julian(20161231)));
   expected_julian.push_back(boost::lexical_cast<std::string>(Cal::date_to_julian(20170101)));
   expected_julian.push_back(boost::lexical_cast<std::string>(Cal::date_to_julian(20170102)));
   expected_julian.push_back(boost::lexical_cast<std::string>(Cal::date_to_julian(20170103)));
   expected_julian.push_back(boost::lexical_cast<std::string>(Cal::date_to_julian(20170104)));
   expected_julian.push_back(boost::lexical_cast<std::string>(Cal::date_to_julian(20170105)));
   expected_julian.push_back(boost::lexical_cast<std::string>(Cal::date_to_julian(20170106)));

   for(int i = 0; i < 7; i++) {

      rep.update_repeat_genvar();
      std::vector<Variable> vec;
      rep.gen_variables(vec);
      BOOST_CHECK_MESSAGE(vec.size() == 6,"expected 6 generated variables but found " << vec.size());

      {const Variable& var = rep.find_gen_variable("YMD");
      BOOST_CHECK_MESSAGE(!var.empty(),"Did not find generated variable YMD_YYYY");
      BOOST_CHECK_MESSAGE(var.theValue() == expected_YMD[i], "expected YMD " << expected_YMD[i] << " but found " << var.theValue() );}

      {const Variable& var = rep.find_gen_variable("YMD_YYYY");
      BOOST_CHECK_MESSAGE(!var.empty(),"Did not find generated variable YMD_YYYY");
      BOOST_CHECK_MESSAGE(var.theValue() == expected_year[i], "expected year to be " << expected_year[i] << " but found " << var.theValue() );}

      {const Variable& var = rep.find_gen_variable("YMD_MM");
      BOOST_CHECK_MESSAGE(!var.empty(),"Did not find generated variable YMD_MM");
      BOOST_CHECK_MESSAGE(var.theValue() == expected_MM[i], "expected month to be " << expected_MM[i] << " but found " << var.theValue() );}

      {const Variable& var = rep.find_gen_variable("YMD_DD");
      BOOST_CHECK_MESSAGE(!var.empty(),"Did not find generated variable YMD_DD");
      BOOST_CHECK_MESSAGE(var.theValue() == expected_day_of_month[i], "expected day of month to be " << expected_day_of_month[i] << " but found " << var.theValue() );}

      {const Variable& var = rep.find_gen_variable("YMD_DOW");
      BOOST_CHECK_MESSAGE(!var.empty(),"Did not find generated variable YMD_DOW");
      BOOST_CHECK_MESSAGE(var.theValue() == expected_day_of_week[i], "expected day of week to be " << expected_day_of_week[i] << " but found " << var.theValue() );}

      {const Variable& var = rep.find_gen_variable("YMD_JULIAN");
      BOOST_CHECK_MESSAGE(!var.empty(),"Did not find generated variable YMD_JULIAN");
      BOOST_CHECK_MESSAGE(var.theValue() == expected_julian[i], "expected " <<  expected_julian[i] << " but found " << var.theValue() );}

      rep.increment();
   }
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: ecmwf/ecflow

max_issues_repo_name: CoollRock/ecflow

max_forks_repo_name: CoollRock/ecflow


text:
/*
 * File:   options.cc
 * Author: Thomas Gatter <thomas(at)bioinf.uni-leipzig.de>
 *
 * Created on November 5, 2015, 5:35 PM
 */

#include "options.h"
#include "Logger/logger.h"

#include <iostream>
#include <boost/program_options.hpp>

#include <sstream>

namespace po = boost::program_options;

options* options::instance = NULL;

options::options() {}

options::~options() {
    if (instance) {
        delete instance;
    }
}

options* options::Instance()
{
   if (!instance)   // Only allow one instance of class to be generated.
      instance = new options;

   return instance;
}

void options::init(int argc, char **argv) {
    po::variables_map vm;

    po::options_description basic_o("Basic options");
    basic_o.add_options()
    ("gtf-guide,g", po::value<std::string>(), "Path to a gtf/gff file containing reference genes. (default: none)")
    ("guide-trustlevel", po::value<unsigned int>(), "Level of trust in the given guides. 0 no trust. 100 maximal trust. Abstract non-linear variable! (default: 20)")
    ("pool,w", po::value<unsigned int>(), "Number of consecutive inputs to merge internally in groups.")
    //("diff-exp-groups,e", po::value<std::string>(), "Input grouping for differential expression by index of inputs, e.g. '1-2;3-4'; or '1;2;' .")
    ("threads,t", po::value<unsigned int>(), "Number of threads to use in parallel. (default: 1)")
    ("out-dir,o", po::value<std::string>(), "The output directory for all data. (default: ./)")
    ("library-type,l", po::value<std::string>(), "fr-unstranded, fr-firststrand, fr-secondstrand, ff-unstranded, ff-firststrand, or ff-secondstrand according to TopHat and Cufflinks definitions. (default: fr-unstranded)")
    ("unstranded,s", "Add this option to ignore strand information and call everything on + strand. (default: none)")
    ("base-coverage-filter,c", po::value<float>(), "Minimum average coverage for features to be filtered. Sets low-edge-mark, mean-filter, and score-filter (default: 4.0)")
    #ifdef ALLOW_DEBUG
    ("debug,d", "Show debug information.")
    #endif
    ("help,h", "Show this help message.")
    ;

    po::options_description general_o("General options");
    general_o.add_options()
    ("no-parse-heuristic", "If several input files are used, use this to disable the heuristic to merge fragments. Increases needed RAM. (default: use heuristic)")
    ("compute-singles", "If several input files are used, use this to compute transcripts for all individual transcripts. (default: only joined output)")
    ("nc", po::value<unsigned int>(), "Number of chromosomes processed in parallel. (# of threads = nc * ng; default: 1)")
    ("ng", po::value<unsigned int>(), "Number of graph per chromosome processed in parallel. (# of threads = nc * ng; default: 1)")
    //("print-graphs", "Produce files with intermediate graphs of all genes for each chromosome. (default: no)")
    ;

    po::options_description exon_o("Exon building options");
    exon_o.add_options()
    ("pos-merge", po::value<unsigned int>(), "Positions within this range of bases will be clustered together. (default: 1)")
    //("min-cov", po::value<unsigned int>(), "Minimum coverage to support an exon per dataset. (default: 1)")
    ("min-intron-length", po::value<unsigned int>(), "Minimal length of predicted introns. (default: 5)")
    ("max-intron-length", po::value<unsigned int>(), "Maximal length of predicted introns. (default: 1,000,000)")
    ;

    po::options_description graph_o("Graph building and flow options");
    graph_o.add_options()
    ("no-denoising", "Add this option to disable denoising of flow graph capacities.")
    ("keep-introns", "Add this option to keep all introns with read coverage intact.")
    ("intron-threshold", po::value<unsigned int>(), "Percentage of coverage to existing splices needed to keep introns intact. (default: 30%)")
    ("broken-intron-threshold", po::value<unsigned int>(), "Percentage of coverage to existing splices needed to keep fragmented intron pieces intact. (default: 15%)")
    ("exon-join-distance", po::value<unsigned int>(), "Join exons no more distant than this amount of bp into one. (default: 5)")
    ("no-trimming", "Disable trimming of predicted transcripts based on coverage.")
    ("trimming-rate", po::value<unsigned int>(), "Don't join exons if one is smaller than this percentage of the bigger (default: 20%)")
    ;

    po::options_description graph_filter_o("Graph filter options");
    graph_filter_o.add_options()
    ("low-edge-mark", po::value<float>(), "Capacity of edges in the splitgraph considered unlikely. (default: 4.0)")
    //("minimal-capacity", po::value<unsigned int>(), "Minimum capacity of edges in the splitgraph. (default: 1)")
    //("arc-filter-percentage", po::value<unsigned int>(), "Arcs accounting for less than this percentage of capacity on a node are removed. (default: 8%)" )
    ("min-junction-coverage", po::value<unsigned int>(), "Minimal coverage to consider intron junctions in the graph. (default: 1)" )
    ("min-junction-anchor", po::value<unsigned int>(), "Minimal length of bp evidence needed left and right of a junction to consider it. (default: 10)" )
    ("group-vote-low", po::value<unsigned int>(), "Multi assembly percentage required for simple consensus voting (default: 30%)" )
    ("group-vote-high", po::value<unsigned int>(), "Multi assembly percentage required for super-majority consensus voting (default: 60%)" )
    ;

    po::options_description filter_o("Transcript output filter options");
    filter_o.add_options()
    ("percent-filter,p", po::value<unsigned int>(), "Minimum capacity to report retrieved transcripts compared to the largest transcript found. (default: 0%)")
    ("mean-filter", po::value<float>(), "Minimum average capacity to report retrieved transcripts. (default: 4.0)")
    ("score-filter", po::value<float>(), "Minimum score to report retrieved transcripts. (default: 3.0)")
    ("min-single-coverage", po::value<unsigned int>(), "Minimal average coverage off single exon transcripts to report. (default: 20)" )
    ("min-single-length", po::value<unsigned int>(), "Minimal length off single exon transcripts to report. (default: 300)" )
    ("min-transcript-length-base", po::value<unsigned int>(), "Minimal length of a transcripts to report in bp. (default: 200)" )
    ("min-transcript-length-extension", po::value<unsigned int>(), "Additional length in bp required per exon. (default: 50)" )
    ("region-group-filter", po::value<float>(), "Regions where all transcripts are below this coverage are discarded. (default: 5.5)")
    ;

    po::options_description tech_o("Advanced options");
    tech_o.add_options()
    ("min-readlength,r", po::value<unsigned int>(), "Reads below this length will not be used for atom evidence. (default: 30)")
    ("min-paired-distance,x", po::value<unsigned int>(), "Minimal distance between two paired reads in order to be considered. (default: 0)")
    ("max-paired-distance,y", po::value<unsigned int>(), "Maximal distance between two paired reads in order to be considered. (default: 100000)")
    ("arc-granularity", po::value<unsigned int>(), "Maximum number of arcs per original arc on pseudo-polynomial convex cost flows. (default: 500)")
    ("min-raw-exon-length", po::value<unsigned int>(), "Minimal number of basepairs needed to constitute a raw exon. (default: 3)")
    ("max-path-enumeration", po::value<unsigned int>(), "Maximal number of distinct paths enumerated on each side of an ambiguous node. (default: 10,000)")
    ;

    po::options_description hidden("");
    hidden.add_options()
        ("exon-counting", "Secret mode to output only exon counts.")
        ("sam", po::value<std::vector<std::string> >(), "Input alignment Bam/Sam")
        ;

    po::positional_options_description pd;
    pd.add("sam", -1);

    po::options_description opts;
    opts.add(basic_o).add(general_o).add(exon_o).add(graph_o).add(graph_filter_o).add(filter_o).add(tech_o).add(hidden);

    po::store(po::command_line_parser(argc, argv).options(opts).positional(pd).run(),vm);

    if(vm.count("help")) {
        std::cout << "Use as: ./ryuto [options]* <input1.bam> <input2.bam> ..." << std::endl << std::endl;
        std::cout << basic_o << std::endl << std::endl;
        std::cout << " ----- Advanced Options ----- " << std::endl << std::endl;
        std::cout << general_o << std::endl;
        std::cout << exon_o << std::endl;
        std::cout << graph_o << std::endl;
        std::cout << graph_filter_o << std::endl;
        std::cout << filter_o << std::endl;
        std::cout << tech_o << std::endl;
        std::cout << "(Version 1.6.2)" << std::endl;
        std::exit(0);
    }

//    if(vm.count("print-graphs")) {
//        print_graphs = true;
//    }

    if(vm.count("debug")) {
        debug = true;
    } else {
        debug = false;
    }

    if(vm.count("exon-counting")) {
        secret_exon_mode = true;
    }

    if(!vm.count("sam")) {
        logger::Instance()->error("No Input BAM/SAM file.");
        std::exit(1);
    }
    bam_files = vm["sam"].as<std::vector<std::string>>();
    for (std::vector<std::string>::iterator bf_it = bam_files.begin(); bf_it != bam_files.end(); ++bf_it) {
        if (!file_exists(*bf_it)) {
            logger::Instance()->error("One or more specified BAM/SAM files do not exist.");
            std::exit(1);
        }
    }

    if (vm.count("guide-trustlevel")) {
         guide_trust_level = vm["guide-trustlevel"].as<unsigned int>() / 100.0;
    }

    if (vm.count("gtf-guide")) {
        gtf_file = vm["gtf-guide"].as<std::string>();
        if (!file_exists(gtf_file)) {
            logger::Instance()->error("GTF guide specified but does not exist.");
            std::exit(1);
        }
        if (guide_trust_level < 0.6) {
            percent_filter = guide_trust_level * 10 + 4;// EXTRA SECURITY
        } else {
            percent_filter = 10;
        }
    } else {
        gtf_file = "";
    }

    if (vm.count("pool")) {
         pool = vm["pool"].as<unsigned int>();
    }

    /*if (vm.count("diff-exp-groups")) {

         // assume grouping is correct
        unsigned int group_counter = 1;
        unsigned int id_counter = 0;

        std::string dfs = vm["diff-exp-groups"].as<std::string>();
        std::stringstream ss(dfs);
        std::string item;
        while (std::getline(ss, item, ';'))
        {
            if (item.empty()) {
                continue;
            }

            std::vector<unsigned int> new_group;

            std::size_t found = item.find("-");
            if (found == std::string::npos) {  // no range, assume single index
                int i = std::stoi(item);
                new_group.push_back(i);
                input_to_id[i-1] = id_counter;
                id_counter++;
            } else {
                int is = std::stoi(item.substr(0, found-1));
                int ie = std::stoi(item.substr(found+1));
                for ( unsigned int i = is; i <= ie ; ++i) {
                    new_group.push_back(i);
                    input_to_id[i-1] = id_counter + (i - is) / pool;
                }
                id_counter += (ie - is) / pool;
            }
            group_to_inputs[group_counter] = new_group;
            group_counter++;
        }

        for(unsigned int i = 0; i< bam_files.size(); ++i) {
            if ( input_to_id.find(i) == input_to_id.end()){
                // id was not found in grouping, kill this!
                logger::Instance()->error("Inputs and Groups do not match.");
                std::exit(1);
            }
        }

        grouped = true;
    } else { */
        grouped = false;

        for(unsigned int i = 0; i< bam_files.size(); ++i) {
            input_to_id[i] = i / pool;
        }

   // }

    if (vm.count("threads")){
       parallel_chromosomes = vm["threads"].as<unsigned int>();
       parallel_graphs = 1;
    } else {
        if (vm.count("nc")){
            parallel_chromosomes = vm["nc"].as<unsigned int>();

            if (parallel_chromosomes < 1) {
                logger::Instance()->error("Number of threads nc must be > 0.");
                std::exit(1);
            }

        } else {
            parallel_chromosomes = 1;
        }
        if (vm.count("ng")){
            parallel_graphs = vm["ng"].as<unsigned int>();

            if (parallel_graphs < 1) {
                logger::Instance()->error("Number of threads ng must be > 0.");
                std::exit(1);
            }

        } else {
            parallel_graphs = 1;
        }
    }

    if (vm.count("out-dir")) {
        outdir = vm["out-dir"].as<std::string>();
    } else {
        outdir = "./";
    }

    if(vm.count("unstranded")) {
        stranded = false;
    }

    if (vm.count("library-type")) {
        std::string type = vm["library-type"].as<std::string>();

        if (type == "fr-unstranded") {
            stranded = true;
            strand_type = unknown;
        } else if (type == "fr-firststrand") {
            stranded = true;
            strand_type = RF;
        } else if (type == "fr-secondstrand") {
            stranded = true;
            strand_type = FR;
        } else if (type == "ff-unstranded") {
            stranded = true;
            strand_type = FF;
        } else if (type == "ff-firststrand") {
            stranded = true;
            strand_type = FF;
        } else if (type == "ff-secondstrand") {
            stranded = true;
            strand_type = RR;
        }
    }

    if(vm.count("base-coverage-filter")) {
        low_edge_mark = vm["base-coverage-filter"].as<float>();
        mean_filter = low_edge_mark;
        minimal_score = low_edge_mark - 1;
    }

    if (vm.count("low-edge-mark")) {
        low_edge_mark = vm["low-edge-mark"].as<float>();
    }

    if (vm.count("mean-filter")) {
        mean_filter = vm["mean-filter"].as<float>();
    }

    if (vm.count("score-filter")) {
         minimal_score = vm["score-filter"].as<float>();
    }

    if (vm.count("no-parse-heuristic")) {
         parse_heuristic = false;
    }

    if (vm.count("compute-singles")) {
         compute_all_singles = true;
    }

    if(vm.count("pos-merge")){
        max_pos_extend = vm["pos-merge"].as<unsigned int>();
    }

//    if(vm.count("min-cov")){
//        min_coverage = vm["min-cov"].as<unsigned int>();
//    }

    if (vm.count("min-intron-length")) {
         min_intron_length = vm["min-intron-length"].as<unsigned int>();
    }
    if (vm.count("max-intron-length")) {
         maximal_intron_size = vm["max-intron-length"].as<unsigned int>();
    }

    if(vm.count("no-denoising")) {
        graph_denoising = false;
    }
    if (vm.count("keep-introns")) {
         keep_introns = true;
    }

    if (vm.count("intron-threshold")) {
         intron_retention_threshold = vm["intron-threshold"].as<unsigned int>();
    }
    if (vm.count("broken-intron-threshold")) {
         broken_intron_retention_threshold = vm["broken-intron-threshold"].as<unsigned int>();
    }

    if (vm.count("exon-join-distance")) {
         exon_join_distance = vm["exon-join-distance"].as<unsigned int>();
    }

    if (vm.count("no-trimming")) {
         trimming = false;
    }

    if (vm.count("trimming-rate")) {
         trimming_rate = vm["trimming-rate"].as<unsigned int>() / 100.0;
    }

    if (vm.count("min-junction-coverage")) {
         min_junction_coverage = vm["min-junction-coverage"].as<unsigned int>();
    }
    if (vm.count("min-junction-anchor")) {
         min_junction_anchor = vm["min-junction-anchor"].as<unsigned int>();
    }

    if (vm.count("group-vote-low")) {
        vote_percentage_low = vm["group-vote-low"].as<unsigned int>();
    }
    if (vm.count("group-vote-high")) {
        vote_percentage_high = vm["group-vote-high"].as<unsigned int>();
    }

    if (vm.count("percent-filter")) {
         percent_filter = vm["percent-filter"].as<unsigned int>();
    }

    if (vm.count("min-single-coverage")) {
        min_single_coverage = vm["min-single-coverage"].as<unsigned int>();
    }

    if (vm.count("min-single-length")) {
        min_single_length = vm["min-single-length"].as<unsigned int>();
    }

    if (vm.count("min-transcript-length-base")) {
         min_transcript_length_base = vm["min-transcript-length-base"].as<unsigned int>();
    }
    if (vm.count("min-transcript-length-extension")) {
         min_transcript_length_extension= vm["min-transcript-extension"].as<unsigned int>();
    }

    if (vm.count("region-group-filter")) {
         group_mean_min = vm["region-group-filter"].as<float>();
    }

    if (vm.count("min-readlengt")) {
        min_readlength = vm["min-readlengt"].as<unsigned int>();
        min_readlength_set = true;
    }

    if (vm.count("min-paired-distance")) {
         min_paired_distance = vm["min-paired-distance"].as<unsigned int>();
    }

    if (vm.count("max-paired-distance")) {
         max_paired_distance = vm["max-paired-distance"].as<unsigned int>();
    }

    if (vm.count("arc-granularity")) {
        max_arc_split = vm["arc-granularity"].as<unsigned int>();
    }

    if (vm.count("min-raw-exon-length")) {
        min_raw_exon_size = vm["min-raw-exon-length"].as<unsigned int>();
    }

    if (vm.count("max-path-enumeration")) {
         max_path_enumeration = vm["max-path-enumeration"].as<unsigned int>();
    }

//    if(vm.count("disjoint-input")) {
//        disjoint_input = true;
//    }

//    if (vm.count("capacity-filter")) {
//         capacity_filter = vm["capacity-filter"].as<unsigned int>();
//    }

//    if (vm.count("minimal-capacity")) {
//         minimal_edge_capacity = vm["minimal-capacity"].as<unsigned int>();
//    }

    if (vm.count("max-flow-iteration")) {
         max_flow_iteration = vm["max-flow-iteration"].as<unsigned int>();
    }
//    if (vm.count("arc-filter-percentage")) {
//        arc_filter = vm["arc-filter-percentage"].as<unsigned int>();
//    }

//    if (!disjoint_input) {
//        minimal_edge_capacity = minimal_edge_capacity * bam_files.size();
//        capacity_filter = capacity_filter * bam_files.size();
//        min_single_coverage = min_single_coverage * bam_files.size();
//    }

}

ext: cc

max_stars_repo_name: studla/RYUTO

max_issues_repo_name: studla/RYUTO

max_forks_repo_name: studla/RYUTO


text:
#pragma once

#include <bitset>
#include <functional>
#include <numeric>
#include <stdexcept>
#include <vector>

#include <dtl/dtl.hpp>
#include <dtl/bits.hpp>
#include <dtl/math.hpp>
#include <dtl/simd.hpp>

#include "immintrin.h"

#include <boost/integer/static_min_max.hpp>

#include "blocked_bloomfilter_block_logic_sgew.hpp"
#include "vector_helper.hpp"

namespace dtl {

//===----------------------------------------------------------------------===//
// Recursive template to work with blocks consisting of multiple sectors,
// whereas a sector corresponds to a native processor word.
//
// In contrast to a sectorized block, the bits are not set/tested in ALL
// sectors. Instead, multiple sectors are grouped to z zones, and k/z bits are
// set in each zone. Within each zone, only a single word (=sector) is accessed.
// This scheme allows to spread out the k bits over larger blocks
// (preferably 512 bits) rather than s*S bits, while the sequential access
// pattern is retained.
//===----------------------------------------------------------------------===//
template<
    typename _key_t,              // the key type
    typename _word_t,             // the word type
    u32 _word_cnt,                // the number of words per block
    u32 z,                        // the numbers of zones (must be a power of two)
    u32 _k,                       // the number of bits to set/test
    template<typename Ty, u32 i> class hasher,      // the hash function family to use
    typename hash_value_t,        // the hash value type to use

    u32 hash_fn_idx,              // current hash function index (used for recursion)
    u32 remaining_hash_bit_cnt,   // the number of remaining hash bits (used for recursion)
    u32 remaining_zone_cnt,       // the remaining number of zones (used for recursion)

    u1 early_out = false          // allows for branching out during lookups (before the next sector is tested)
>
struct multizone_block {

  static_assert(early_out == false, "The early-out feature is not supported.");
  static_assert(z < _word_cnt, "The number of zones must be less than the number of words per block.");

  //===----------------------------------------------------------------------===//
  // Static part
  //===----------------------------------------------------------------------===//
  using key_t = _key_t;
  using word_t = _word_t;

  static constexpr u32 word_cnt = _word_cnt;
  static_assert(dtl::is_power_of_two(word_cnt), "Parameter 'word_cnt' must be a power of two.");
  static constexpr u32 sector_cnt = word_cnt;
  static constexpr u32 sector_cnt_log2 = dtl::ct::log_2<sector_cnt>::value;

  static constexpr u32 zone_cnt = z;
  static_assert(dtl::is_power_of_two(zone_cnt), "Parameter 'zone_cnt' must be a power of two.");
  static constexpr u32 current_zone_idx = zone_cnt - remaining_zone_cnt;

  static constexpr u32 hash_value_bitlength = sizeof(hash_value_t) * 8;

  static constexpr u32 k = _k;
  static constexpr u32 k_cnt_per_zone = k / zone_cnt;
  static_assert(k % zone_cnt == 0, "Parameter 'k' must be dividable by 'z'.");

  static constexpr u32 word_cnt_per_zone = word_cnt / zone_cnt;
  static_assert(word_cnt % zone_cnt == 0, "Parameter 'word_cnt' must be dividable by 'z'.");
  __forceinline__ __host__ __device__
  static constexpr word_t zone_mask() { return static_cast<word_t>(word_cnt_per_zone) - 1; }

  // The number of hash bits required to determine the sector within a zone.
  static constexpr u32 hash_bit_cnt_per_zone = dtl::ct::log_2_u32<word_cnt_per_zone>::value;

  // Rehash if necessary
  static constexpr u1 rehash = remaining_hash_bit_cnt < hash_bit_cnt_per_zone;
  static constexpr u32 hash_fn_idx_after_rehash = rehash ? hash_fn_idx + 1 : hash_fn_idx;
  static constexpr u32 remaining_hash_bit_cnt_after_rehash = rehash ? hash_value_bitlength : remaining_hash_bit_cnt;

  //===----------------------------------------------------------------------===//
  // Insert
  //===----------------------------------------------------------------------===//
  __forceinline__
  static void
  insert(word_t* __restrict block_ptr, const key_t key) noexcept {

    hash_value_t hash_val = 0;

    // Call the recursive function
    static constexpr u32 remaining_hash_bits = 0;
    multizone_block<key_t, word_t, word_cnt, zone_cnt, k,
                    hasher, hash_value_t, hash_fn_idx, remaining_hash_bits,
                    remaining_zone_cnt, early_out>
      ::insert(block_ptr, key, hash_val);
  }
  //===----------------------------------------------------------------------===//

  //===----------------------------------------------------------------------===//
  // Insert (Recursive)
  //===----------------------------------------------------------------------===//
  __forceinline__
  static void
  insert(word_t* __restrict block_ptr, const key_t key, hash_value_t& hash_val) noexcept {

    // Rehash if necessary
    hash_val = rehash ? hasher<key_t, hash_fn_idx>::hash(key) : hash_val;

    // Word index within zone
    constexpr u32 shift = remaining_hash_bit_cnt_after_rehash - hash_bit_cnt_per_zone;
    u32 word_idx_within_zone = (hash_val >> shift) & zone_mask(); // TODO consider using bit-extract

    // Word index within block
    u32 word_idx = (word_cnt_per_zone * current_zone_idx) + word_idx_within_zone;

    // Load the word of interest
    word_t word = block_ptr[word_idx];

    word_t bit_mask = 0;

    using word_block_t =
      word_block<key_t, word_t, 1 /*sector_cnt_per_word*/, k_cnt_per_zone,
                 hasher, hash_value_t, hash_fn_idx_after_rehash, remaining_hash_bit_cnt_after_rehash - hash_bit_cnt_per_zone,
                 k_cnt_per_zone>;
    word_block_t::which_bits(key, hash_val, bit_mask);

    // Update the bit vector
    word |= bit_mask;
    block_ptr[word_idx] = word;

    // Process remaining zones recursively, if any
    using block_t =
      multizone_block<key_t, word_t, word_cnt, zone_cnt, k,
                      hasher, hash_value_t,
                      word_block_t::hash_fn_idx_end, word_block_t::remaining_hash_bits,
                      remaining_zone_cnt - 1>;
    block_t::insert(block_ptr, key, hash_val);
  }
  //===----------------------------------------------------------------------===//

  //===----------------------------------------------------------------------===//
  // Contains
  //===----------------------------------------------------------------------===//
  __forceinline__ __unroll_loops__ __host__ __device__
  static u1
  contains(const word_t* __restrict block_ptr, const key_t key) noexcept {

    hash_value_t hash_val = 0;

    // Call the recursive function
    static constexpr u32 remaining_hash_bits = 0;
    return multizone_block<key_t, word_t, word_cnt, zone_cnt, k,
                           hasher, hash_value_t, hash_fn_idx, remaining_hash_bits,
                           remaining_zone_cnt, early_out>
      ::contains(block_ptr, key, hash_val, true);
  }
  //===----------------------------------------------------------------------===//

  //===----------------------------------------------------------------------===//
  // Contains (Recursive)
  //===----------------------------------------------------------------------===//
  __forceinline__ __unroll_loops__ __host__ __device__
  static u1
  contains(const word_t* __restrict block_ptr, const key_t key, hash_value_t& hash_val, u1 is_contained_in_block) noexcept {

    // Rehash if necessary
    hash_val = rehash ? hasher<key_t, hash_fn_idx>::hash(key) : hash_val;

    // Word index within zone
    constexpr u32 shift = remaining_hash_bit_cnt_after_rehash - hash_bit_cnt_per_zone;
    u32 word_idx_within_zone = (hash_val >> shift) & zone_mask(); // TODO consider using bit-extract

    // Word index within block
    u32 word_idx = (word_cnt_per_zone * current_zone_idx) + word_idx_within_zone;

    // Load the word of interest
    word_t word = block_ptr[word_idx];

    word_t bit_mask = 0;

    using word_block_t =
      word_block<key_t, word_t, 1 /*sector_cnt_per_word*/, k_cnt_per_zone,
                 hasher, hash_value_t, hash_fn_idx_after_rehash, remaining_hash_bit_cnt_after_rehash - hash_bit_cnt_per_zone,
                 k_cnt_per_zone>;
    word_block_t::which_bits(key, hash_val, bit_mask);

    // Bit testing
    u1 found_in_zone = (word & bit_mask) == bit_mask;

    // Process remaining zones recursively, if any
    using block_t =
      multizone_block<key_t, word_t, word_cnt, zone_cnt, k,
                      hasher, hash_value_t,
                      word_block_t::hash_fn_idx_end, word_block_t::remaining_hash_bits,
                      remaining_zone_cnt - 1>;
    return block_t::contains(block_ptr, key, hash_val, found_in_zone & is_contained_in_block);
  }
  //===----------------------------------------------------------------------===//

  //===----------------------------------------------------------------------===//
  // Contains (SIMD)
  //===----------------------------------------------------------------------===//
  template<u64 n>
  __forceinline__ __unroll_loops__
  static auto
  contains(const vec<key_t,n>& keys,
           const word_t* __restrict bitvector_base_address,
           const vec<hash_value_t,n>& block_start_word_idxs) noexcept {

    vec<hash_value_t, n> hash_vals(0);
    const auto is_contained_in_block_mask = vec<word_t,n>::mask::make_all_mask(); // true

    // Call recursive function
    static constexpr u32 remaining_hash_bits = 0;
    return multizone_block<key_t, word_t, word_cnt, z, k,
                           hasher, hash_value_t, hash_fn_idx, remaining_hash_bits,
                           remaining_zone_cnt, early_out>
      ::contains(keys, hash_vals, bitvector_base_address, block_start_word_idxs, is_contained_in_block_mask);

  }
  //===----------------------------------------------------------------------===//

  //===----------------------------------------------------------------------===//
  // Contains (SIMD, Recursive)
  //===----------------------------------------------------------------------===//
  template<u64 n>
  __forceinline__ __unroll_loops__
  static auto
  contains(const vec<key_t,n>& keys,
           vec<hash_value_t,n>& hash_vals,
           const word_t* __restrict bitvector_base_address,
           const vec<hash_value_t,n>& block_start_word_idxs,
           const typename vec<word_t,n>::mask is_contained_in_block_mask) noexcept {

    // Rehash if necessary
    hash_vals = rehash ? hasher<vec<key_t, n>, hash_fn_idx>::hash(keys) : hash_vals;

    // Word index within zone
    constexpr u32 shift = remaining_hash_bit_cnt_after_rehash - hash_bit_cnt_per_zone;
    auto word_idx_within_zone = (hash_vals >> shift) & zone_mask();

    // Word index (abs)
    auto word_idxs = block_start_word_idxs + word_idx_within_zone + (word_cnt_per_zone * current_zone_idx);

    // Load the words of interest
    const auto words = internal::vector_gather<word_t, hash_value_t, n>::gather(bitvector_base_address, word_idxs);

    vec<word_t,n> bit_masks = 0;

    using word_block_t =
      word_block<key_t, word_t, 1 /*sector_cnt_per_word*/, k_cnt_per_zone,
                 hasher, hash_value_t, hash_fn_idx_after_rehash, remaining_hash_bit_cnt_after_rehash - hash_bit_cnt_per_zone,
                 k_cnt_per_zone>;
    word_block_t::which_bits(keys, hash_vals, bit_masks);

    // Bit testing
    typename vec<word_t,n>::mask found_in_zone = (words & bit_masks) == bit_masks;

    // Process remaining zones recursively, if any
    using block_t =
      multizone_block<key_t, word_t, word_cnt, zone_cnt, k,
                      hasher, hash_value_t,
                      word_block_t::hash_fn_idx_end, word_block_t::remaining_hash_bits,
                      remaining_zone_cnt - 1>;
    return block_t::contains(keys, hash_vals, bitvector_base_address, block_start_word_idxs, found_in_zone & is_contained_in_block_mask);
  }
  //===----------------------------------------------------------------------===//

};

//===----------------------------------------------------------------------===//
template<
    typename key_t,               // the key type
    typename word_t,              // the word type
    u32 word_cnt,                 // the number of words per block
    u32 z,                        // the numbers of zones (must be a power of two)
    u32 k,                        // the number of bits to set/test
    template<typename Ty, u32 i> class hasher,      // the hash function family to use
    typename hash_value_t,        // the hash value type to use

    u32 hash_fn_idx,              // current hash function index (used for recursion)
    u32 remaining_hash_bit_cnt,   // the number of remaining hash bits (used for recursion)

    u1 early_out                  // allows for branching out during lookups (before the next sector is tested)
>
struct multizone_block<key_t, word_t, word_cnt, z, k, hasher, hash_value_t, hash_fn_idx, remaining_hash_bit_cnt,
                       0 /* no more remaining zones */, early_out>  {

  //===----------------------------------------------------------------------===//
  // Insert
  //===----------------------------------------------------------------------===//
  __forceinline__
  static void
  insert(word_t* __restrict block_ptr, const key_t key, hash_value_t& hash_val) noexcept {
    // End of recursion.
  }
  //===----------------------------------------------------------------------===//

  //===----------------------------------------------------------------------===//
  // Contains
  //===----------------------------------------------------------------------===//
  __forceinline__ __host__ __device__
  static u1
  contains(const word_t* __restrict block_ptr, const key_t key, hash_value_t& hash_val, u1 is_contained_in_block) noexcept {
    // End of recursion.
    return is_contained_in_block;
  }
  //===----------------------------------------------------------------------===//

  //===----------------------------------------------------------------------===//
  // Contains (SIMD)
  //===----------------------------------------------------------------------===//
  template<u64 n>
  __forceinline__ __unroll_loops__
  static auto
  contains(const vec<key_t,n>& keys,
           vec<hash_value_t,n>& hash_vals,
           const word_t* __restrict bitvector_base_address,
           const vec<key_t,n>& block_start_word_idxs,
           const typename vec<word_t,n>::mask is_contained_in_block_mask) noexcept {
    // End of recursion.
    return is_contained_in_block_mask;
  }
  //===----------------------------------------------------------------------===//

};

} // namespace dtl

ext: hpp

max_stars_repo_name: peterboncz/bloomfilter-bsd

max_issues_repo_name: tum-db/partitioned-filters

max_forks_repo_name: tum-db/partitioned-filters


text:
/**
 * Copyright Soramitsu Co., Ltd. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef KAGOME_CORE_API_TRANSPORT_BEAST_HTTP_SESSION_HPP
#define KAGOME_CORE_API_TRANSPORT_BEAST_HTTP_SESSION_HPP

#include <chrono>
#include <cstdlib>
#include <memory>

#include <boost/beast.hpp>
#include "api/transport/session.hpp"
#include "common/logger.hpp"

namespace kagome::api {
  /**
   * @brief HTTP session for api service
   */
  class HttpSession : public Session,
                      public std::enable_shared_from_this<HttpSession> {
    template <typename Body>
    using Request = boost::beast::http::request<Body>;

    template <typename Body>
    using Response = boost::beast::http::response<Body>;

    using StringBody = boost::beast::http::string_body;

    template <class Body>
    using RequestParser = boost::beast::http::request_parser<Body>;

    using HttpField = boost::beast::http::field;

    using HttpError = boost::beast::http::error;
    using Logger = common::Logger;

   public:
    using Socket = boost::asio::ip::tcp::socket;

    struct Configuration {
      static constexpr size_t kDefaultRequestSize = 10000u;
      static constexpr Duration kDefaultTimeout = std::chrono::seconds(30);

      size_t max_request_size{kDefaultRequestSize};
      Duration operation_timeout{kDefaultTimeout};
    };

    ~HttpSession() override = default;

    /**
     * @brief constructor
     * @param socket socket instance
     * @param config session configuration
     */
    HttpSession(Socket socket, Configuration config);

    /**
     * @brief starts session
     */
    void start() override;

    /**
     * @brief sends response wrapped by http message
     * @param response message to send
     */
    void respond(std::string_view response) override;

   private:
    /**
     * @brief stops session
     */
    void stop();

    /**
     * @brief process http request, compose and execute response
     * @tparam Body request body type
     * @param request request
     */
    template <class Body>
    void handleRequest(Request<Body> &&request);

    /**
     * @brief asynchronously read http message
     */
    void asyncRead();

    /**
     * @brief sends http message
     * @tparam Message http message type
     * @param message http message
     */
    template <class Message>
    void asyncWrite(Message &&message);

    /**
     * @brief read completion callback
     */
    void onRead(boost::system::error_code ec, std::size_t size);

    /**
     * @brief write completion callback
     */
    void onWrite(boost::system::error_code ec, std::size_t, bool close);

    /**
     * @brief composes `bad request` message
     * @param message text to send
     * @param version protocol version
     * @param keep_alive true if server should keep connection alive, false
     * otherwise
     * @return composed request
     */
    auto makeBadResponse(std::string_view message,
                         unsigned version,
                         bool keep_alive);

    /**
     * @brief reports error code and message
     * @param ec error code
     * @param message error message
     */
    void reportError(boost::system::error_code ec, std::string_view message);

    static constexpr std::string_view kServerName = "Kagome extrinsic api";

    Configuration config_;              ///< session configuration
    boost::beast::tcp_stream stream_;   ///< stream
    boost::beast::flat_buffer buffer_;  ///< read buffer

    /**
     * @brief request parser type
     */
    using Parser = RequestParser<StringBody>;

    std::unique_ptr<Parser> parser_;                        ///< http parser
    Logger logger_ = common::createLogger("http session");  ///< logger instance
  };

}  // namespace kagome::api

#endif  // KAGOME_CORE_API_TRANSPORT_BEAST_HTTP_SESSION_HPP

max_stars_repo_name: lamafab/kagome

max_issues_repo_name: lamafab/kagome

max_forks_repo_name: lamafab/kagome


text:
/*
author: Kris Gonzalez
date: 190416
objective: want to do a quick test using eigen library for matrices. using start example from below
source: https://eigen.tuxfamily.org/dox/GettingStarted.html
KJG200118: get eigen by cloning this repo: https://gitlab.com/libeigen/eigen

HOW TO COMPILE:
    g++ -std=c++11 -I C:\Users\kris\repos\eigen\ .\quick_demo.cpp
*/

#include <iostream>
#include <Eigen/Dense>
using Eigen::MatrixXd;
int main()
{
  MatrixXd m(2,2);
  m(0,0) = 3;
  m(1,0) = 2.5;
  m(0,1) = -1;
  m(1,1) = m(1,0) + m(0,1);
  std::cout << m << std::endl;
}

ext: cpp

max_stars_repo_name: kjgonzalez/codefiles

max_issues_repo_name: kjgonzalez/codefiles

max_forks_repo_name: kjgonzalez/codefiles


text:
#include <iostream>
#include <Eigen/Dense>
#include "../simple_lib/include/simple_activation.h"

using namespace Eigen;

int main(){
    using std::cout;
    using std::endl;

    MatrixXd a = MatrixXd::Zero(3, 1);
    MatrixXd s1 = MatrixXd::Zero(3, 1);
    MatrixXd s2 = MatrixXd::Zero(3, 1);
    a << 1010, 1000, 990;

    s1 = a.array().exp();
    s1 /= s1.sum();

    cout << s1 << endl;

    s2 = MyDL::softmax(a);

    cout << s2 << endl;

    return 0;
}


text:
// ---------------------------------------------------------------------
// pion:  a Boost C++ framework for building lightweight HTTP interfaces
// ---------------------------------------------------------------------
// Copyright (C) 2007-2014 Splunk Inc.  (https://github.com/splunk/pion)
//
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
//

#ifndef __PION_SPDYPARSER_HEADER__
#define __PION_SPDYPARSER_HEADER__

#include <pion/config.hpp>

#include <boost/shared_ptr.hpp>
#include <boost/logic/tribool.hpp>
#include <boost/system/error_code.hpp>
#include <boost/thread/once.hpp>
#include <pion/logger.hpp>
#include <pion/spdy/types.hpp>
#include <pion/spdy/decompressor.hpp>

#ifndef BOOST_SYSTEM_NOEXCEPT
    #ifndef BOOST_NOEXCEPT
        #define BOOST_SYSTEM_NOEXCEPT
    #else
        #define BOOST_SYSTEM_NOEXCEPT BOOST_NOEXCEPT
    #endif
#endif

namespace pion {    // begin namespace pion
namespace spdy {    // begin namespace spdy

///
/// parser : parsers and reads the SPDY frames
///

class PION_API parser
{
public:

    /// class-specific error code values
    enum error_value_t {
        ERROR_INVALID_SPDY_FRAME = 1,
        ERROR_INVALID_SPDY_VERSION,
        ERROR_DECOMPRESSION,
        ERROR_PROTOCOL_ERROR,
        ERROR_INTERNAL_SPDY_ERROR,
        ERROR_MISSING_HEADER_DATA
    };

    /// class-specific error category
    class error_category_t
        : public boost::system::error_category
    {
    public:
        const char *name() const BOOST_SYSTEM_NOEXCEPT { return "SPDYParser"; }
        std::string message(int ev) const {
            switch (ev) {
                case ERROR_INVALID_SPDY_FRAME:
                    return "invalid spdy frame";
                case ERROR_INVALID_SPDY_VERSION:
                    return "invalid spdy version";
                case ERROR_DECOMPRESSION:
                    return "error in decompression";
                case ERROR_MISSING_HEADER_DATA:
                    return "missing header data";

            }
            return "SPDYParser error";
        }
    };

    /// constructs a new parser object (default constructor)
    parser();

    /// destructor
    ~parser() {}

    /**
     * parse a SPDY packet
     *
     * @return boost::tribool result of parsing:
     *                        false = SPDY frame has an error,
     *                        true = finished parsing SPDY frame,
     *                        indeterminate = not yet finished parsing SPDY frame
     */
    boost::tribool parse(http_protocol_info& http_headers,
                         boost::system::error_code& ec,
                         const decompressor_ptr& decompressor,
                         const char *packet_ptr,
                         boost::uint32_t& length_packet,
                         boost::uint32_t current_stream_count);

    /// Get the pointer to the first character to the spdy data contect
    const char * get_spdy_data_content( ) { return m_last_data_chunk_ptr; }

    /// Get the pointer to the first character to the spdy data contect
    const char * get_spdy_read_pointer( ) { return m_read_ptr; }

    /**
     * checks if the frame is spdy frame or not
     *
     * @return true if it is a frame else returns false
     */
    static spdy_frame_type get_spdy_frame_type(const char *ptr);

    /**
     * checks if the frame is spdy control frame or not
     *
     * @return true if it is a control frame else returns false
     */
    static bool is_spdy_control_frame(const char *ptr);

    /**
     * get the stream id for the spdy control frame
     *
     * @return true if it is a control frame else returns false
     */
    static boost::uint32_t get_control_frame_stream_id(const char *ptr);

protected:

    /// resets the read pointer
    inline void set_read_ptr(const char *ptr) { m_read_ptr = m_current_data_chunk_ptr = ptr; }

    /// populates the frame for every spdy packet
    /// Returns false if there was an error else returns true
    bool populate_frame(boost::system::error_code& ec,
                        spdy_control_frame_info& frame,
                        boost::uint32_t& length_packet,
                        boost::uint32_t& stream_id,
                        http_protocol_info& http_headers);

    /// creates the unique parser error_category_t
    static void create_error_category(void);

    /// returns an instance of parser::error_category_t
    static inline error_category_t& get_error_category(void) {
        boost::call_once(parser::create_error_category, m_instance_flag);
        return *m_error_category_ptr;
    }

    /**
     * sets an error code
     *
     * @param ec error code variable to define
     * @param ev error value to raise
     */
    static inline void set_error(boost::system::error_code& ec, error_value_t ev) {
        ec = boost::system::error_code(static_cast<int>(ev), get_error_category());
    }

    /**
     * parses an the header payload for SPDY
     *
     */
    void parse_header_payload(boost::system::error_code& ec,
                              const decompressor_ptr& decompressor,
                              const spdy_control_frame_info& frame,
                              http_protocol_info& http_headers,
                              boost::uint32_t current_stream_count);

    /**
     * parses the data for SPDY
     *
     */
    void parse_spdy_data(boost::system::error_code& ec,
                         const spdy_control_frame_info& frame,
                         boost::uint32_t stream_id,
                         http_protocol_info& http_info);

    /**
     * parses an the Settings Frame for SPDY
     *
     */
    void parse_spdy_settings_frame(boost::system::error_code& ec,
                                   const spdy_control_frame_info& frame);

    /**
     * parses an the RST stream for SPDY
     *
     */
    void parse_spdy_rst_stream(boost::system::error_code& ec,
                               const spdy_control_frame_info& frame);

    /**
     * parses an the Ping Frame for SPDY
     *
     */
    void parse_spdy_ping_frame(boost::system::error_code& ec,
                               const spdy_control_frame_info& frame);

    /**
     * parses an the GoAway Frame for SPDY
     *
     */
    void parse_spdy_goaway_frame(boost::system::error_code& ec,
                                 const spdy_control_frame_info& frame);

    /**
     * parses an the WindowUpdate Frame for SPDY
     *
     */
    void parse_spdy_window_update_frame(boost::system::error_code& ec,
                                        const spdy_control_frame_info& frame);

    /**
     * parse a SPDY frame (protected implementation)
     *
     * @return boost::tribool result of parsing:
     *                        false = SPDY frame has an error,
     *                        true = finished parsing SPDY frame,
     *                        indeterminate = not yet finished parsing SPDY frame
     */
    boost::tribool parse_spdy_frame(boost::system::error_code& ec,
                                    const decompressor_ptr& decompressor,
                                    http_protocol_info& http_headers,
                                    boost::uint32_t& length_packet,
                                    boost::uint32_t current_stream_count);

private:

    /// generic read pointer which parses the spdy data
    const char *                        m_read_ptr;

    /// points to the first character of the uncompressed http headers
    const char *                        m_uncompressed_ptr;

    /// SPDY has interleaved frames and this will point to start of the current chunk data
    const char *                        m_current_data_chunk_ptr;

    /// SPDY has interleaved frames and this will point to start of the the last chunk data
    const char *                        m_last_data_chunk_ptr;

    /// primary logging interface used by this class
    mutable logger                      m_logger;

    /// points to a single and unique instance of the HTTPParser ErrorCategory
    static error_category_t *           m_error_category_ptr;

    /// used to ensure thread safety of the HTTPParser ErrorCategory
    static boost::once_flag             m_instance_flag;
};

/// data type for a spdy reader pointer
typedef boost::shared_ptr<parser>       parser_ptr;

}   // end namespace spdy
}   // end namespace pion

#endif

max_stars_repo_name: odant/conan-pion

max_issues_repo_name: odant/conan-pion

max_forks_repo_name: odant/conan-pion


text:
/*<-
Copyright (c) 2016 Barrett Adair

Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
->*/

#include <boost/callable_traits/is_transaction_safe.hpp>
#include "test.hpp"

template<typename Safe, typename NotSafe>
void test() {

    CT_ASSERT( is_transaction_safe<Safe>::value
        // for when tx safe is disabled
        || std::is_same<Safe, NotSafe>::value);
    CT_ASSERT(! is_transaction_safe<NotSafe>::value);
}

#define TEST_TRANSACTION_SAFE(not_safe) \
    test<not_safe BOOST_CLBL_TRTS_TRANSACTION_SAFE_SPECIFIER, not_safe>()

int main() {

    TEST_TRANSACTION_SAFE(int(*)());

    #ifndef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
    TEST_TRANSACTION_SAFE(int(...) volatile LREF);
    TEST_TRANSACTION_SAFE(int() const);
    #endif

    TEST_TRANSACTION_SAFE(int(*)(...));

    struct foo;

    TEST_TRANSACTION_SAFE(int(foo::*)());
    TEST_TRANSACTION_SAFE(int(foo::*)() const volatile);
    TEST_TRANSACTION_SAFE(int(foo::*)(...));
    TEST_TRANSACTION_SAFE(int(foo::*)(...) const volatile RREF);
}


text:
#define BOOST_TEST_DYN_LINK

#include <boost/test/parameterized_test.hpp>
#include <boost/test/unit_test.hpp>
//#include <boost/mpl/list.hpp>

#include "testmatch/enums.hpp"
#include "testmatch/helpers.hpp"

#include <exception>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

BOOST_AUTO_TEST_SUITE(test_header_utility)

BOOST_AUTO_TEST_CASE(testfunc_split_str) {
    std::vector<std::string> expected;

    // Boundary case - empty string
    BOOST_TEST(split_str("").empty());

    // Boundary case - just delimeter
    expected.push_back("");
    expected.push_back("");
    BOOST_TEST(split_str(",") == expected);
    expected.clear();

    // Boundary case - no delimeter
    expected.push_back("test");
    BOOST_TEST(split_str("test") == expected);
    expected.clear();

    // Standard case - default delimeter
    expected.push_back("a");
    expected.push_back("b");
    expected.push_back("c");
    BOOST_TEST(split_str("a,b,c") == expected);

    // Standard case - delimeter at end
    expected.push_back("");
    BOOST_TEST(split_str("a,b,c,") == expected);

    // Standard case - delimeter at start
    expected.pop_back();
    expected.insert(expected.begin(), "");
    BOOST_TEST(split_str(",a,b,c") == expected);
    expected.clear();

    // Standard case - other delimeter
    expected.push_back("1");
    expected.push_back("2");
    expected.push_back("3");
    BOOST_TEST(split_str("1 2 3", " ") == expected);

    // Standard case - other delimeter
    BOOST_TEST(split_str("1thisisadelimeter2thisisadelimeter3",
                         "thisisadelimeter") == expected);
}

BOOST_AUTO_TEST_CASE(testfunc_balls_to_ov) {
    std::pair<int, int> out = balls_to_ov(0);
    BOOST_TEST((out.first == 0) & (out.second == 0));

    out = balls_to_ov(1);
    BOOST_TEST((out.first == 0) & (out.second == 1));

    out = balls_to_ov(6);
    BOOST_TEST((out.first == 1) & (out.second == 0));

    out = balls_to_ov(11);
    BOOST_TEST((out.first == 1) & (out.second == 5));

    out = balls_to_ov(7);
    BOOST_TEST((out.first == 1) & (out.second == 1));

    out = balls_to_ov(480);
    BOOST_TEST((out.first == 80) & (out.second == 0));
}

BOOST_AUTO_TEST_CASE(testfunc_is_slow_bowler) {
    BowlType types[6] = {med, med_fast, fast_med, fast, offbreak, legbreak};
    bool expected[6] = {true, false, false, false, true, true};

    for (int i = 0; i < 6; i++) {
        BOOST_TEST(is_slow_bowler(types[i]) == expected[i]);
    }
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: LiamBlake/TestMatch-Backend

max_issues_repo_name: LiamBlake/TestMatch

max_forks_repo_name: LiamBlake/TestMatch