<commit_before>// $Id: ClassTest_test.C,v 1.6 2001/05/07 00:10:38 oliver Exp $
#include <BALL/CONCEPT/classTest.h>

using namespace BALL;

START_TEST(ClassTest, "$Id: ClassTest_test.C,v 1.6 2001/05/07 00:10:38 oliver Exp $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

CHECK("CHECK(string)")
RESULT

CHECK("RESULT")
RESULT

CHECK("NEW_TMP_FILE(filename)")
	String tmp_filename;
	NEW_TMP_FILE(tmp_filename);
	TEST::this_test = (tmp_filename != "");
RESULT

CHECK("PRECISION(a)")
	PRECISION(0.5)
	TEST_EQUAL(TEST::precision, 0.5)
RESULT

CHECK("TEST_REAL_EQUAL(a, b)")
	PRECISION(0.011)
	TEST_REAL_EQUAL(1.0, 1.01)
	TEST_REAL_EQUAL(1.0, 1.0)
	TEST_REAL_EQUAL(-1.0, -1.01)
	TEST_REAL_EQUAL(-1.01, -1.0)
RESULT

CHECK("TEST_EQUAL(a, b)")
	TEST_EQUAL(1.0, 1.0)
	TEST_EQUAL('A', 'A')
RESULT

CHECK("TEST_NOT_EQUAL(a, b)")
	TEST_NOT_EQUAL(0, 1)
	TEST_NOT_EQUAL('A', 'B')
RESULT

CHECK("TEST_EXCEPTION(a, b)")
	TEST_EXCEPTION(Exception::NullPointer, throw Exception::NullPointer(__FILE__, __LINE__))
RESULT

CHECK("STATUS(a)")
	STATUS("status message")
RESULT

CHECK("TEST_FILE(filename, templatename, use_regexps)")
	TEST_FILE("data/class_test_infile.txt", "data/class_test_template.txt", false)
	TEST_FILE("data/class_test_infile.txt", "data/class_test_regexp_template.txt", true)
RESULT

CHECK("CAPTURE_OUTPUT(level)/COMPARE_OUTPUT(text)")
	CAPTURE_OUTPUT(123)
		Log.level(123) << "TEST123" << std::endl;
		Log.level(124) << "TEST124" << std::endl;
		Log.level(122) << "TEST122" << std::endl;
	COMPARE_OUTPUT("TEST123\n")

	CAPTURE_OUTPUT(123);
		Log.level(124) << "TEST124" << std::endl;
	COMPARE_OUTPUT("")

	CAPTURE_OUTPUT(124)
		Log.level(124) << "TEST124" << std::endl;
	COMPARE_OUTPUT("TEST124\n")
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<commit_msg>added: test foir ABORT_IF macro<commit_after>// $Id: ClassTest_test.C,v 1.7 2001/12/07 00:47:07 oliver Exp $
#include <BALL/CONCEPT/classTest.h>

using namespace BALL;

START_TEST(ClassTest, "$Id: ClassTest_test.C,v 1.7 2001/12/07 00:47:07 oliver Exp $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

CHECK("CHECK(string)")
RESULT

CHECK("RESULT")
RESULT

CHECK("NEW_TMP_FILE(filename)")
	String tmp_filename;
	NEW_TMP_FILE(tmp_filename);
	TEST::this_test = (tmp_filename != "");
RESULT

CHECK("PRECISION(a)")
	PRECISION(0.5)
	TEST_EQUAL(TEST::precision, 0.5)
RESULT

CHECK("TEST_REAL_EQUAL(a, b)")
	PRECISION(0.011)
	TEST_REAL_EQUAL(1.0, 1.01)
	TEST_REAL_EQUAL(1.0, 1.0)
	TEST_REAL_EQUAL(-1.0, -1.01)
	TEST_REAL_EQUAL(-1.01, -1.0)
RESULT

CHECK("TEST_EQUAL(a, b)")
	TEST_EQUAL(1.0, 1.0)
	TEST_EQUAL('A', 'A')
RESULT

CHECK("TEST_NOT_EQUAL(a, b)")
	TEST_NOT_EQUAL(0, 1)
	TEST_NOT_EQUAL('A', 'B')
RESULT

CHECK("TEST_EXCEPTION(a, b)")
	TEST_EXCEPTION(Exception::NullPointer, throw Exception::NullPointer(__FILE__, __LINE__))
RESULT

CHECK("STATUS(a)")
	STATUS("status message")
RESULT

CHECK("TEST_FILE(filename, templatename, use_regexps)")
	TEST_FILE("data/class_test_infile.txt", "data/class_test_template.txt", false)
	TEST_FILE("data/class_test_infile.txt", "data/class_test_regexp_template.txt", true)
RESULT

CHECK("ABORT_IF(condition)")
	ABORT_IF(true)
	TEST_EQUAL(1, 0)
RESULT

CHECK("CAPTURE_OUTPUT(level)/COMPARE_OUTPUT(text)")
	CAPTURE_OUTPUT(123)
		Log.level(123) << "TEST123" << std::endl;
		Log.level(124) << "TEST124" << std::endl;
		Log.level(122) << "TEST122" << std::endl;
	COMPARE_OUTPUT("TEST123\n")

	CAPTURE_OUTPUT(123);
		Log.level(124) << "TEST124" << std::endl;
	COMPARE_OUTPUT("")

	CAPTURE_OUTPUT(124)
		Log.level(124) << "TEST124" << std::endl;
	COMPARE_OUTPUT("TEST124\n")
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
// Copyright (C) 2006-2009 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

// boost
#include <boost/program_options.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/convenience.hpp>
namespace po = boost::program_options;
namespace fs = boost::filesystem;

// standard
#include <vector>
#include <iostream>

// VisionWorkbench
#include <vw/Math.h>
#include <vw/Camera/ControlNetwork.h>
#include <vw/InterestPoint/InterestData.h>

using namespace vw;
using namespace vw::ip;
using namespace vw::camera;

#if VW_BOOST_VERSION < 103400
std::istream& operator>>(std::istream& is, fs::path& p) {
    std::string s;
    is >> s;
    p = s;
    return is;
}
#endif

// Main Executable
int main( int argc, char *argv[] ) {
  std::string cnet_file;
  std::string image_mean_file;
  fs::path output_cnet_file;
  fs::path output_deleted_index_file;
  ControlNetwork cnet("ControlNetwork Editor");
  double cutoff_sigma;
  std::string output_cnet_file_tmp;
  std::string output_deleted_index_file_tmp;
  std::string data_dir;

  po::options_description general_options("Options");
  general_options.add_options()
    ("cutoff_sigma,c", po::value<double>(&cutoff_sigma)->default_value(2),"This is the highend cutoff sigma.")
    ("output_cnet_file,o", po::value<std::string>(&output_cnet_file_tmp)->default_value("processed.cnet"), "Name of processed control network file to write out.")
    ("output_deleted_index_file,o", po::value<std::string>(&output_deleted_index_file_tmp)->default_value("cnet_deleted.txt"), "Name of file of indexes to deleted control points to write out.")
    ("data_dir,d",po::value<std::string>(&data_dir)->default_value("."), "Name of directory to write output files into.")
    ("help,h","Brings up this.");

  po::options_description positional_options("Positional Options");
  positional_options.add_options()
    ("cnet", po::value<std::string>(&cnet_file), "Control Network")
    ("image-mean", po::value<std::string>(&image_mean_file), "Image Mean file");

  po::positional_options_description positional_options_desc;
  positional_options_desc.add("cnet", 1);
  positional_options_desc.add("image-mean",1);

  po::options_description all_options("Allowed Options");
  all_options.add(general_options).add(positional_options);

  po::variables_map vm;
  po::store( po::command_line_parser( argc, argv ).options(all_options).positional(positional_options_desc).run(), vm );
  po::notify( vm );

  std::ostringstream usage;
  usage << "Usage: " << argv[0] << " [options] <cnet> <image-mean>\n\n";
  usage << general_options << std::endl;

  if ( vm.count("help") ||
       !vm.count("cnet") ||
       !vm.count("image-mean") ) {
    vw_out() << usage.str() << std::endl;
    return 1;
  }

  output_cnet_file = output_cnet_file_tmp;
  output_deleted_index_file = output_deleted_index_file_tmp;

  // Loading control network file
  std::vector<std::string> tokens;
  boost::split( tokens, cnet_file, boost::is_any_of(".") );
  if ( tokens[tokens.size()-1] == "net" ) {
    cnet.read_isis( cnet_file );
  } else if ( tokens[tokens.size()-1] == "cnet" ) {
    cnet.read_binary( cnet_file );
  } else {
    vw_throw( IOErr() << "Unknown Control Network file extension, \""
                << tokens[tokens.size()-1] << "\"." );
  }

  // Alright loading image mean file
  std::ifstream f;
  f.open( image_mean_file.c_str(), std::ios::binary | std::ios::in );
  unsigned read_cnet_size;
  f.read((char*)&(read_cnet_size), sizeof(unsigned));
  if ( read_cnet_size != cnet.size() )
    vw_throw( IOErr() << "Image mean file doesn't seem to match Cnet" );
  unsigned error_size;
  std::list<double> image_errors;
  f.read((char*)&(error_size), sizeof(unsigned));

  for ( uint i = 0; i < error_size; i++ ) {
    double temp;
    f.read((char*)&(temp), sizeof(double));
    image_errors.push_back(temp);
  }

  // Collecting statistics
  double min_image = *(std::min_element(image_errors.begin(),
                                       image_errors.end()));
  double max_image = *(std::max_element(image_errors.begin(),
                                        image_errors.end()));
  double mean_image=0, stddev_image=0;
  for( std::list<double>::iterator it = image_errors.begin();
       it != image_errors.end(); it++ ) {
    mean_image += (*it);
    stddev_image += (*it)*(*it);
  }
  mean_image /= error_size;
  stddev_image /=  error_size;
  stddev_image = sqrt( stddev_image - mean_image*mean_image );
  vw_out() << "Image min: " << min_image << " max: " << max_image
            << " mean: " << mean_image << " stddev: " << stddev_image
            << std::endl;

  // Awesome, now clipping based one std_dev
  int clipping_count = 0;
  int other_count = 0;
  int cp_clip_count = 0;
  std::list<double>::iterator image_error = image_errors.begin();
  std::vector<bool> deleted(cnet.size(), false);
  int del_i = 0;
  for ( unsigned cpi = 0; cpi < cnet.size(); cpi++, del_i++ ) {
    for ( unsigned cmi = 0; cmi < cnet[cpi].size(); cmi++ ) {
      if ( image_error == image_errors.end() )
        vw_throw( IOErr() << "Internal overflow error" );

      // Do clipping
      if ( *image_error >= mean_image + stddev_image*cutoff_sigma ) {
        clipping_count++;

        cnet[cpi].delete_measure( cmi );
        cmi--;
      } else
        other_count++;

      image_error++;
    }

    if ( cnet[cpi].size() < 2 ) {
      cnet.delete_control_point( cpi );
      cpi--;
      cp_clip_count++;
      deleted[del_i] = true;
    }
  }
  vw_out() << float(clipping_count) * 100.0 / float(clipping_count + other_count)
            << "% (" << clipping_count << ") of the control measures removed.\n";
  vw_out() << float(cp_clip_count) * 100.0 / float(cp_clip_count+cnet.size())
            << "% (" << cp_clip_count << ") of control points removed.\n";

  vw_out() << "\nWriting out new control network\n";
  std::string outfile_str = fs::path(data_dir / output_cnet_file.branch_path() / fs::basename(output_cnet_file)).string();
  cnet.write_binary(outfile_str);

  vw_out() << "\nWriting deleted index file\n";
  std::string delindex_file_str = fs::path(data_dir / output_deleted_index_file.branch_path() / fs::basename(output_deleted_index_file)).string();

  std::ofstream di_out(delindex_file_str.c_str());
  for ( uint i = 0; i < deleted.size()-1; i++)
    di_out << deleted[i] << " ";
  di_out << deleted[deleted.size()-1] << "\n";
  di_out.close();
}
<commit_msg>Fix so cnet can actually output new control network<commit_after>// __BEGIN_LICENSE__
// Copyright (C) 2006-2009 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

// boost
#include <boost/program_options.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/convenience.hpp>
namespace po = boost::program_options;
namespace fs = boost::filesystem;

// standard
#include <vector>
#include <iostream>

// VisionWorkbench
#include <vw/Math.h>
#include <vw/Camera/ControlNetwork.h>
#include <vw/InterestPoint/InterestData.h>

using namespace vw;
using namespace vw::ip;
using namespace vw::camera;

#if VW_BOOST_VERSION < 103400
std::istream& operator>>(std::istream& is, fs::path& p) {
    std::string s;
    is >> s;
    p = s;
    return is;
}
#endif

// Main Executable
int main( int argc, char *argv[] ) {
  std::string cnet_file;
  std::string image_mean_file;
  fs::path output_cnet_file;
  fs::path output_deleted_index_file;
  ControlNetwork cnet("ControlNetwork Editor");
  double cutoff_sigma;
  std::string output_cnet_file_tmp;
  std::string output_deleted_index_file_tmp;
  std::string data_dir;

  po::options_description general_options("Options");
  general_options.add_options()
    ("cutoff_sigma,c", po::value<double>(&cutoff_sigma)->default_value(2),"This is the highend cutoff sigma.")
    ("output_cnet_file,o", po::value<std::string>(&output_cnet_file_tmp)->default_value("processed.cnet"), "Name of processed control network file to write out.")
    ("output_deleted_index_file,o", po::value<std::string>(&output_deleted_index_file_tmp)->default_value("cnet_deleted.txt"), "Name of file of indexes to deleted control points to write out.")
    ("data_dir,d",po::value<std::string>(&data_dir)->default_value("."), "Name of directory to write output files into.")
    ("help,h","Brings up this.");

  po::options_description positional_options("Positional Options");
  positional_options.add_options()
    ("cnet", po::value<std::string>(&cnet_file), "Control Network")
    ("image-mean", po::value<std::string>(&image_mean_file), "Image Mean file");

  po::positional_options_description positional_options_desc;
  positional_options_desc.add("cnet", 1);
  positional_options_desc.add("image-mean",1);

  po::options_description all_options("Allowed Options");
  all_options.add(general_options).add(positional_options);

  po::variables_map vm;
  po::store( po::command_line_parser( argc, argv ).options(all_options).positional(positional_options_desc).run(), vm );
  po::notify( vm );

  std::ostringstream usage;
  usage << "Usage: " << argv[0] << " [options] <cnet> <image-mean>\n\n";
  usage << general_options << std::endl;

  if ( vm.count("help") ||
       !vm.count("cnet") ||
       !vm.count("image-mean") ) {
    vw_out() << usage.str() << std::endl;
    return 1;
  }

  output_cnet_file = output_cnet_file_tmp;
  output_deleted_index_file = output_deleted_index_file_tmp;

  // Loading control network file
  std::vector<std::string> tokens;
  boost::split( tokens, cnet_file, boost::is_any_of(".") );
  if ( tokens[tokens.size()-1] == "net" ) {
    cnet.read_isis( cnet_file );
  } else if ( tokens[tokens.size()-1] == "cnet" ) {
    cnet.read_binary( cnet_file );
  } else {
    vw_throw( IOErr() << "Unknown Control Network file extension, \""
                << tokens[tokens.size()-1] << "\"." );
  }

  // Alright loading image mean file
  std::ifstream f;
  f.open( image_mean_file.c_str(), std::ios::binary | std::ios::in );
  unsigned read_cnet_size;
  f.read((char*)&(read_cnet_size), sizeof(unsigned));
  if ( read_cnet_size != cnet.size() )
    vw_throw( IOErr() << "Image mean file doesn't seem to match Cnet" );
  unsigned error_size;
  std::list<double> image_errors;
  f.read((char*)&(error_size), sizeof(unsigned));

  for ( uint i = 0; i < error_size; i++ ) {
    double temp;
    f.read((char*)&(temp), sizeof(double));
    image_errors.push_back(temp);
  }

  // Collecting statistics
  double min_image = *(std::min_element(image_errors.begin(),
                                       image_errors.end()));
  double max_image = *(std::max_element(image_errors.begin(),
                                        image_errors.end()));
  double mean_image=0, stddev_image=0;
  for( std::list<double>::iterator it = image_errors.begin();
       it != image_errors.end(); it++ ) {
    mean_image += (*it);
    stddev_image += (*it)*(*it);
  }
  mean_image /= error_size;
  stddev_image /=  error_size;
  stddev_image = sqrt( stddev_image - mean_image*mean_image );
  vw_out() << "Image min: " << min_image << " max: " << max_image
            << " mean: " << mean_image << " stddev: " << stddev_image
            << std::endl;

  // Awesome, now clipping based one std_dev
  int clipping_count = 0;
  int other_count = 0;
  int cp_clip_count = 0;
  std::list<double>::iterator image_error = image_errors.begin();
  std::vector<bool> deleted(cnet.size(), false);
  int del_i = 0;
  for ( unsigned cpi = 0; cpi < cnet.size(); cpi++, del_i++ ) {
    for ( unsigned cmi = 0; cmi < cnet[cpi].size(); cmi++ ) {
      if ( image_error == image_errors.end() )
        vw_throw( IOErr() << "Internal overflow error" );

      // Do clipping
      if ( *image_error >= mean_image + stddev_image*cutoff_sigma ) {
        clipping_count++;

        cnet[cpi].delete_measure( cmi );
        cmi--;
      } else
        other_count++;

      image_error++;
    }

    if ( cnet[cpi].size() < 2 ) {
      cnet.delete_control_point( cpi );
      cpi--;
      cp_clip_count++;
      deleted[del_i] = true;
    }
  }
  vw_out() << float(clipping_count) * 100.0 / float(clipping_count + other_count)
            << "% (" << clipping_count << ") of the control measures removed.\n";
  vw_out() << float(cp_clip_count) * 100.0 / float(cp_clip_count+cnet.size())
            << "% (" << cp_clip_count << ") of control points removed.\n";

  vw_out() << "\nWriting out new control network\n";
  std::string outfile_str = fs::path(data_dir / output_cnet_file ).string();
  vw_out() << "\tfile: " << outfile_str << "\n";
  cnet.write_binary(outfile_str);

  vw_out() << "\nWriting deleted index file\n";
  std::string delindex_file_str = fs::path(data_dir / output_deleted_index_file ).string();
  vw_out() << "\tfile: " << delindex_file_str << "\n";

  std::ofstream di_out(delindex_file_str.c_str());
  for ( uint i = 0; i < deleted.size()-1; i++)
    di_out << deleted[i] << " ";
  di_out << deleted[deleted.size()-1] << "\n";
  di_out.close();
}
<|endoftext|>


<commit_before>#ifndef ARC_STL_WRAPPERS
#define ARC_STL_WRAPPERS

#include <algorithm>

namespace arc_std{

    /**
     *  Returns the index of element in vector v
     *   or returns -1 of element is not in v
     */
    template<typename T>
    inline int find(const std::vector<T>& v, const T& element)
    {
        auto it = std::find(v.begin(), v.end(), element);
        if(it == v.end())
        {
            return -1;
        }
        return std::distance(v.begin(), it);
    }
}

#endif //ARC_STL_WRAPPERS
<commit_msg>Made  const<commit_after>#ifndef ARC_STL_WRAPPERS
#define ARC_STL_WRAPPERS

#include <algorithm>

namespace arc_std{

    /**
     *  Returns the index of element in vector v
     *   or returns -1 of element is not in v
     */
    template<typename T>
    inline int find(const std::vector<T>& v, const T& element)
    {
        const auto it = std::find(v.begin(), v.end(), element);
        if(it == v.end())
        {
            return -1;
        }
        return std::distance(v.begin(), it);
    }
}

#endif //ARC_STL_WRAPPERS
<|endoftext|>


<commit_before>#ifndef ASMITH_SERIALISER_HPP
#define ASMITH_SERIALISER_HPP

// Copyright 2017 Adam Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <deque>
#include <list>
#include "serial_value.hpp"

namespace as {

	template<class T, class ENABLE = void>
	struct serialiser {
		typedef T serialise_t;
		typedef T deserialise_t;

		static serial_value serialise(serialise_t);
		static deserialise_t deserialise(const serial_value&);
	};

	// -- Helper functions

	template<class T, class ENABLE = void>
	struct string_serialiser {
		typedef typename serialiser<T>::serialise_t serialise_t;
		typedef typename serialiser<T>::deserialise_t deserialise_t;

		static serial_value::string_t serialise(serialise_t);
		static deserialise_t deserialise(const serial_value::string_t&);
	};

	// -- Helper Specialisations

	template<class T>
	struct string_serialiser<T, typename std::enable_if<
		std::is_same<T, uint8_t>::value ||
		std::is_same<T, uint16_t>::value ||
		std::is_same<T, uint32_t>::value ||
		std::is_same<T, uint64_t>::value
	>::type> {
		typedef T serialise_t;
		typedef T deserialise_t;
		enum{ CONVERTABLE = 0 };

		static serial_value::string_t serialise(serialise_t aValue) {
			return std::to_string(aValue);
		}

		static deserialise_t deserialise(const serial_value::string_t& aValue) {
			return static_cast<T>(std::stoull(aValue));
		}
	};

	template<class T>
	struct string_serialiser<T, typename std::enable_if<
		std::is_same<T, int8_t>::value ||
		std::is_same<T, int16_t>::value ||
		std::is_same<T, int32_t>::value ||
		std::is_same<T, int64_t>::value
	>::type> {
		typedef T serialise_t;
		typedef T deserialise_t;
		enum { CONVERTABLE = 1 };

		static serial_value::string_t serialise(serialise_t aValue) {
			return std::to_string(aValue);
		}

		static deserialise_t deserialise(const serial_value::string_t& aValue) {
			return static_cast<T>(std::stoll(aValue));
		}
	};

	template<class T>
	struct string_serialiser<T, typename std::enable_if<
		std::is_same<T, float>::value ||
		std::is_same<T, double>::value
	>::type> {
		typedef T serialise_t;
		typedef T deserialise_t;
		enum { CONVERTABLE = 1 };

		static serial_value::string_t serialise(serialise_t aValue) {
			return std::to_string(aValue);
		}

		static deserialise_t deserialise(const serial_value::string_t& aValue) {
			return static_cast<T>(std::stod(aValue));
		}
	};

	template<>
	struct string_serialiser<char, void> {
		typedef char serialise_t;
		typedef char deserialise_t;
		enum { CONVERTABLE = 1 };

		static serial_value::string_t serialise(serialise_t aValue) {
			return serial_value::string_t() + aValue;
		}

		static deserialise_t deserialise(const serial_value::string_t& aValue) {
			return aValue[0];
		}
	};

	template<>
	struct string_serialiser<bool, void> {
		typedef bool serialise_t;
		typedef bool deserialise_t;
		enum { CONVERTABLE = 1 };

		static serial_value::string_t serialise(serialise_t aValue) {
			return aValue ? "true" : "false";
		}

		static deserialise_t deserialise(const serial_value::string_t& aValue) {
			if(aValue == "true") {
				return true;
			}else if (aValue == "false") {
				return false;
			}else {
				throw std::runtime_error("as::string_serialiser::deserialise : String cannot be converted to bool");
			}
		}
	};

	template<>
	struct string_serialiser<serial_value::string_t, void> {
		typedef const serial_value::string_t& serialise_t;
		typedef const serial_value::string_t& deserialise_t;
		enum { CONVERTABLE = 1 };

		static serial_value::string_t serialise(serialise_t aValue) {
			return aValue;
		}

		static deserialise_t deserialise(const serial_value::string_t& aValue) {
			return aValue;
		}
	};

	// -- Serialiser Specialisations

	template<>
	struct serialiser<char, void> {
		typedef char serialise_t;
		typedef char deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			return serial_value(aValue);
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			return aValue.get_char();
		}
	};

	template<>
	struct serialiser<bool, void> {
		typedef bool serialise_t;
		typedef bool deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			return serial_value(aValue);
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			return aValue.get_bool();
		}
	};

	template<class T>
	struct serialiser<T, typename std::enable_if<
		std::is_same<T, uint8_t>::value ||
		std::is_same<T, uint16_t>::value ||
		std::is_same<T, uint32_t>::value ||
		std::is_same<T, uint64_t>::value
	>::type> {
		typedef T serialise_t;
		typedef T deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			return serial_value(aValue);
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			return static_cast<deserialise_t>(aValue.get_unsigned());
		}
	};

	template<class T>
	struct serialiser<T, typename std::enable_if<
		std::is_same<T, int8_t>::value ||
		std::is_same<T, int16_t>::value ||
		std::is_same<T, int32_t>::value ||
		std::is_same<T, int64_t>::value
	>::type> {
		typedef T serialise_t;
		typedef T deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			return serial_value(aValue);
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			return static_cast<deserialise_t>(aValue.get_signed());
		}
	};

	template<class T>
	struct serialiser<T, typename std::enable_if<
		std::is_same<T, float>::value ||
		std::is_same<T, double>::value
	>::type> {
		typedef T serialise_t;
		typedef T deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			return serial_value(aValue);
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			return static_cast<deserialise_t>(aValue.get_float());
		}
	};

	template<>
	struct serialiser<std::string, void> {
		typedef const std::string& serialise_t;
		typedef std::string deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			return serial_value(aValue);
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			return aValue.get_string();
		}
	};

	// -- Container specialisations

	template<class T>
	struct serialiser<std::vector<T>, void> {
		typedef const std::vector<T>& serialise_t;
		typedef std::vector<T> deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			serial_value tmp;
			std::vector<serial_value>& values = tmp.set_array();
			for(const T& i : aValue) values.push_back(serialiser<T>::serialise(i));
			return tmp;
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			const std::vector<serial_value>& values = aValue.get_array();
			deserialise_t tmp;
			for(const serial_value& i : values) tmp.push_back(serialiser<T>::deserialise(i));
			return tmp;
		}
	};

	template<class T>
	struct serialiser<std::deque<T>, void> {
		typedef const std::deque<T>& serialise_t;
		typedef std::vector<T> deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			serial_value tmp;
			std::vector<serial_value>& values = tmp.set_array();
			for(const T& i : aValue) values.push_back(serialiser<T>::serialise(i));
			return tmp;
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			const std::vector<serial_value>& values = aValue.get_array();
			deserialise_t tmp;
			for(const serial_value& i : values) tmp.push_back(serialiser<T>::deserialise(i));
			return tmp;
		}
	};

	template<class T>
	struct serialiser<std::list<T>, void> {
		typedef const std::list<T>& serialise_t;
		typedef std::list<T> deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			serial_value tmp;
			std::vector<serial_value>& values = tmp.set_array();
			for(const T& i : aValue) values.push_back(serialiser<T>::serialise(i));
			return tmp;
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			const std::vector<serial_value>& values = aValue.get_array();
			deserialise_t tmp;
			for(const serial_value& i : values) tmp.push_back(serialiser<T>::deserialise(i));
			return tmp;
		}
	};

	template<class T>
	struct serialiser<std::map<std::string,T>, void> {
		typedef const std::map<std::string,T>& serialise_t;
		typedef std::map<std::string,T> deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			serial_value tmp;
			std::map<serial_value::string_t,serial_value>& values = tmp.set_object();
			for(const auto& i : aValue) values.emplace(i.first, serialiser<T>::serialise(i.second));
			return tmp;
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			const std::map<serial_value::string_t, serial_value>& values = aValue.get_object();
			deserialise_t tmp;
			for(const auto& i : values) tmp.emplace(i.first, serialiser<T>::deserialise(i.second));
			return tmp;
		}
	};

	template<class T>
	struct serialiser<std::map<char, T>, void> {
		typedef const std::map<char, T>& serialise_t;
		typedef std::map<char, T> deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			serial_value tmp;
			serial_value::object_t& values = tmp.set_object();
			for(const auto& i : aValue) values.emplace(serial_value::string_t() + i.first, serialiser<T>::serialise(i.second));
			return tmp;
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			const serial_value::object_t& values = aValue.get_object();
			deserialise_t tmp;
			for(const auto& i : values) tmp.emplace(i.first[0], serialiser<T>::deserialise(i.second));
			return tmp;
		}
	};

	template<class K, class T>
	struct serialiser<std::map<K,T>, typename std::enable_if<
		std::is_same<T, uint8_t>::value ||
		std::is_same<T, uint16_t>::value ||
		std::is_same<T, uint32_t>::value ||
		std::is_same<T, uint64_t>::value ||
		std::is_same<T, int8_t>::value ||
		std::is_same<T, int16_t>::value ||
		std::is_same<T, int32_t>::value ||
		std::is_same<T, int64_t>::value ||
		std::is_same<T, float>::value ||
		std::is_same<T, double>::value
	>::type> {
		typedef const std::map<K,T>& serialise_t;
		typedef std::map<K,T> deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			serial_value tmp;
			serial_value::object_t& values = tmp.set_object();
			for(const auto& i : aValue) values.emplace(std::to_string(i.first), serialiser<T>::serialise(i.second));
			return tmp;
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			const serial_value::object_t& values = aValue.get_object();
			deserialise_t tmp;
			for(const auto& i : values) tmp.emplace(static_cast<K>(std::stod(i.first)), serialiser<T>::deserialise(i.second));
			return tmp;
		}
	};

	template<class K, class T>
	struct serialiser<std::map<K,T>, void> {
		typedef const std::map<K,T>& serialise_t;
		typedef std::map<K,T> deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			serial_value tmp;
			std::map<serial_value::string_t, serial_value>& parent = tmp.set_object();
			parent.emplace("keys", serial_value());
			parent.emplace("values", serial_value());
			std::vector<serial_value>& keys = parent.find("keys")->second.set_array();
			std::vector<serial_value>& values = parent.find("values")->second.set_array();

			for(const auto& i : aValue) {
				keys.push_back(serialiser<K>::serialise(i.first));
				values.push_back(serialiser<T>::serialise(i.second));
			}
			return tmp;
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			const std::vector<serial_value>& keys = aValue["keys"].get_array();
			const std::vector<serial_value>& values = aValue["values"].get_array();
			const size_t size = keys.size();
			deserialise_t tmp;

			for(size_t i = 0; i < size; ++i) {
				tmp.emplace(
					serialiser<K>::deserialise(keys[i]),
					serialiser<T>::deserialise(values[i])
				);
			}

			return tmp;
		}
	};
}

#endif<commit_msg>Simplified map key serialisation<commit_after>#ifndef ASMITH_SERIALISER_HPP
#define ASMITH_SERIALISER_HPP

// Copyright 2017 Adam Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <deque>
#include <list>
#include "serial_value.hpp"

namespace as {

	template<class T, class ENABLE = void>
	struct serialiser {
		typedef T serialise_t;
		typedef T deserialise_t;

		static serial_value serialise(serialise_t);
		static deserialise_t deserialise(const serial_value&);
	};

	// -- Helper functions

	template<class T, class ENABLE = void>
	struct string_serialiser {
		typedef typename serialiser<T>::serialise_t serialise_t;
		typedef typename serialiser<T>::deserialise_t deserialise_t;

		static serial_value::string_t serialise(serialise_t);
		static deserialise_t deserialise(const serial_value::string_t&);
	};

	// -- Helper Specialisations

	template<class T>
	struct string_serialiser<T, typename std::enable_if<
		std::is_same<T, uint8_t>::value ||
		std::is_same<T, uint16_t>::value ||
		std::is_same<T, uint32_t>::value ||
		std::is_same<T, uint64_t>::value
	>::type> {
		typedef T serialise_t;
		typedef T deserialise_t;
		enum{ CONVERTABLE = 0 };

		static serial_value::string_t serialise(serialise_t aValue) {
			return std::to_string(aValue);
		}

		static deserialise_t deserialise(const serial_value::string_t& aValue) {
			return static_cast<T>(std::stoull(aValue));
		}
	};

	template<class T>
	struct string_serialiser<T, typename std::enable_if<
		std::is_same<T, int8_t>::value ||
		std::is_same<T, int16_t>::value ||
		std::is_same<T, int32_t>::value ||
		std::is_same<T, int64_t>::value
	>::type> {
		typedef T serialise_t;
		typedef T deserialise_t;
		enum { CONVERTABLE = 1 };

		static serial_value::string_t serialise(serialise_t aValue) {
			return std::to_string(aValue);
		}

		static deserialise_t deserialise(const serial_value::string_t& aValue) {
			return static_cast<T>(std::stoll(aValue));
		}
	};

	template<class T>
	struct string_serialiser<T, typename std::enable_if<
		std::is_same<T, float>::value ||
		std::is_same<T, double>::value
	>::type> {
		typedef T serialise_t;
		typedef T deserialise_t;
		enum { CONVERTABLE = 1 };

		static serial_value::string_t serialise(serialise_t aValue) {
			return std::to_string(aValue);
		}

		static deserialise_t deserialise(const serial_value::string_t& aValue) {
			return static_cast<T>(std::stod(aValue));
		}
	};

	template<>
	struct string_serialiser<char, void> {
		typedef char serialise_t;
		typedef char deserialise_t;
		enum { CONVERTABLE = 1 };

		static serial_value::string_t serialise(serialise_t aValue) {
			return serial_value::string_t() + aValue;
		}

		static deserialise_t deserialise(const serial_value::string_t& aValue) {
			return aValue[0];
		}
	};

	template<>
	struct string_serialiser<bool, void> {
		typedef bool serialise_t;
		typedef bool deserialise_t;
		enum { CONVERTABLE = 1 };

		static serial_value::string_t serialise(serialise_t aValue) {
			return aValue ? "true" : "false";
		}

		static deserialise_t deserialise(const serial_value::string_t& aValue) {
			if(aValue == "true") {
				return true;
			}else if (aValue == "false") {
				return false;
			}else {
				throw std::runtime_error("as::string_serialiser::deserialise : String cannot be converted to bool");
			}
		}
	};

	template<>
	struct string_serialiser<serial_value::string_t, void> {
		typedef const serial_value::string_t& serialise_t;
		typedef const serial_value::string_t& deserialise_t;
		enum { CONVERTABLE = 1 };

		static serial_value::string_t serialise(serialise_t aValue) {
			return aValue;
		}

		static deserialise_t deserialise(const serial_value::string_t& aValue) {
			return aValue;
		}
	};

	// -- Serialiser Specialisations

	template<>
	struct serialiser<char, void> {
		typedef char serialise_t;
		typedef char deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			return serial_value(aValue);
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			return aValue.get_char();
		}
	};

	template<>
	struct serialiser<bool, void> {
		typedef bool serialise_t;
		typedef bool deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			return serial_value(aValue);
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			return aValue.get_bool();
		}
	};

	template<class T>
	struct serialiser<T, typename std::enable_if<
		std::is_same<T, uint8_t>::value ||
		std::is_same<T, uint16_t>::value ||
		std::is_same<T, uint32_t>::value ||
		std::is_same<T, uint64_t>::value
	>::type> {
		typedef T serialise_t;
		typedef T deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			return serial_value(aValue);
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			return static_cast<deserialise_t>(aValue.get_unsigned());
		}
	};

	template<class T>
	struct serialiser<T, typename std::enable_if<
		std::is_same<T, int8_t>::value ||
		std::is_same<T, int16_t>::value ||
		std::is_same<T, int32_t>::value ||
		std::is_same<T, int64_t>::value
	>::type> {
		typedef T serialise_t;
		typedef T deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			return serial_value(aValue);
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			return static_cast<deserialise_t>(aValue.get_signed());
		}
	};

	template<class T>
	struct serialiser<T, typename std::enable_if<
		std::is_same<T, float>::value ||
		std::is_same<T, double>::value
	>::type> {
		typedef T serialise_t;
		typedef T deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			return serial_value(aValue);
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			return static_cast<deserialise_t>(aValue.get_float());
		}
	};

	template<>
	struct serialiser<std::string, void> {
		typedef const std::string& serialise_t;
		typedef std::string deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			return serial_value(aValue);
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			return aValue.get_string();
		}
	};

	// -- Container specialisations

	template<class T>
	struct serialiser<std::vector<T>, void> {
		typedef const std::vector<T>& serialise_t;
		typedef std::vector<T> deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			serial_value tmp;
			std::vector<serial_value>& values = tmp.set_array();
			for(const T& i : aValue) values.push_back(serialiser<T>::serialise(i));
			return tmp;
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			const std::vector<serial_value>& values = aValue.get_array();
			deserialise_t tmp;
			for(const serial_value& i : values) tmp.push_back(serialiser<T>::deserialise(i));
			return tmp;
		}
	};

	template<class T>
	struct serialiser<std::deque<T>, void> {
		typedef const std::deque<T>& serialise_t;
		typedef std::vector<T> deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			serial_value tmp;
			std::vector<serial_value>& values = tmp.set_array();
			for(const T& i : aValue) values.push_back(serialiser<T>::serialise(i));
			return tmp;
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			const std::vector<serial_value>& values = aValue.get_array();
			deserialise_t tmp;
			for(const serial_value& i : values) tmp.push_back(serialiser<T>::deserialise(i));
			return tmp;
		}
	};

	template<class T>
	struct serialiser<std::list<T>, void> {
		typedef const std::list<T>& serialise_t;
		typedef std::list<T> deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			serial_value tmp;
			std::vector<serial_value>& values = tmp.set_array();
			for(const T& i : aValue) values.push_back(serialiser<T>::serialise(i));
			return tmp;
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			const std::vector<serial_value>& values = aValue.get_array();
			deserialise_t tmp;
			for(const serial_value& i : values) tmp.push_back(serialiser<T>::deserialise(i));
			return tmp;
		}
	};

	template<class K, class T>
	struct serialiser<std::map<K,T>, typename std::enable_if<string_serialiser<K>::CONVERTABLE, void>::type> {
		typedef const std::map<K,T>& serialise_t;
		typedef std::map<K,T> deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			serial_value tmp;
			serial_value::object_t& values = tmp.set_object();
			for(const auto& i : aValue) values.emplace(string_serialiser<K>::serialise(i.first), serialiser<T>::serialise(i.second));
			return tmp;
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			const serial_value::object_t& values = aValue.get_object();
			deserialise_t tmp;
			for(const auto& i : values) tmp.emplace(string_serialiser<K>::deserialise(i.first), serialiser<T>::deserialise(i.second));
			return tmp;
		}
	};

	template<class K, class T>
	struct serialiser<std::map<K,T>, typename std::enable_if<! string_serialiser<K>::CONVERTABLE, void>::type> {
		typedef const std::map<K,T>& serialise_t;
		typedef std::map<K,T> deserialise_t;

		static serial_value serialise(serialise_t aValue) {
			serial_value tmp;
			std::map<serial_value::string_t, serial_value>& parent = tmp.set_object();
			parent.emplace("keys", serial_value());
			parent.emplace("values", serial_value());
			std::vector<serial_value>& keys = parent.find("keys")->second.set_array();
			std::vector<serial_value>& values = parent.find("values")->second.set_array();

			for(const auto& i : aValue) {
				keys.push_back(serialiser<K>::serialise(i.first));
				values.push_back(serialiser<T>::serialise(i.second));
			}
			return tmp;
		}

		static deserialise_t deserialise(const serial_value& aValue) {
			const std::vector<serial_value>& keys = aValue["keys"].get_array();
			const std::vector<serial_value>& values = aValue["values"].get_array();
			const size_t size = keys.size();
			deserialise_t tmp;

			for(size_t i = 0; i < size; ++i) {
				tmp.emplace(
					serialiser<K>::deserialise(keys[i]),
					serialiser<T>::deserialise(values[i])
				);
			}

			return tmp;
		}
	};
}

#endif<|endoftext|>


<commit_before>//  (C) Copyright Gennadiy Rozental 2001-2002.
//  (C) Copyright Ullrich Koethe 2001.
//  Permission to copy, use, modify, sell and distribute this software
//  is granted provided this copyright notice appears in all copies.
//  This software is provided "as is" without express or implied warranty,
//  and with no claim as to its suitability for any purpose.

//  See http://www.boost.org for most recent version including documentation.
//
//  File        : $RCSfile$
//
//  Version     : $Id$
//
//  Description : defines all classes in test_case hierarchy and object generators
//  for them.
// ***************************************************************************

#ifndef BOOST_UNIT_TEST_SUITE_HPP
#define BOOST_UNIT_TEST_SUITE_HPP

// Boost.Test
#include <boost/test/detail/unit_test_monitor.hpp>
#include <boost/test/detail/unit_test_config.hpp>
#include <boost/test/detail/class_properties.hpp>

// BOOST
#include <boost/shared_ptr.hpp>

// STL
#include <string>  // for std::string

#define BOOST_TEST_CASE( function ) \
boost::unit_test_framework::create_test_case((function), #function )
#define BOOST_CLASS_TEST_CASE( function, tc_instance ) \
boost::unit_test_framework::create_test_case((function), #function, tc_instance )
#define BOOST_PARAM_TEST_CASE( function, begin, end ) \
boost::unit_test_framework::create_test_case((function), #function, (begin), (end) )
#define BOOST_PARAM_CLASS_TEST_CASE( function, tc_instance, begin, end ) \
boost::unit_test_framework::create_test_case((function), #function, tc_instance, (begin), (end) )
#define BOOST_TEST_SUITE( testsuite_name ) \
( new boost::unit_test_framework::test_suite( testsuite_name ) )

namespace boost {

namespace unit_test_framework {

// ************************************************************************** //
// **************                   test_case                  ************** //
// ************************************************************************** //

class test_case {
public:
    typedef detail::unit_test_monitor::error_level error_level_type;

    // Destructor
    virtual             ~test_case()    {}

    // number of tests in this test case
    virtual unit_test_counter size() const;

    // execute this method to run the test case
    void                run();

    // public properties
    BOOST_READONLY_PROPERTY( int, 2, (test_case,test_suite) )
                        p_timeout;                  // timeout for the excecution monitor
    BOOST_READONLY_PROPERTY( unit_test_counter, 1, (test_suite) )
                        p_expected_failures;        // number of aseertions that are expected to fail in this test case
    BOOST_READONLY_PROPERTY( bool, 0, () )
                        p_type;                     // true = test case, false - test suite
    BOOST_READONLY_PROPERTY( std::string, 0, () )
                        p_name;                     // name for this test case

protected:
    // protected properties
    BOOST_READONLY_PROPERTY( bool, 2, (test_case,test_suite) )
                        p_compound_stage;           // used to properly manage progress report
    BOOST_READWRITE_PROPERTY( unit_test_counter )
                        p_stages_amount;            // number of stages this test consist of; stage could be another test case
                                                    // like with test_suite, another parameterized test for parameterized_test_case
                                                    // or 1 stage that reflect single test_case behaviour

    // access methods
    void                curr_stage_is_compound();

    // Constructor
    explicit            test_case( std::string const&   name_,
                                   bool                 type_,
                                   unit_test_counter    stages_number_,
                                   bool                 monitor_run_    = true );

    // test case implementation hooks to be called with unit_test_monitor or alone
    virtual void        do_init()       {}
    virtual void        do_run()        {}
    virtual void        do_destroy()    {}

private:
    // Data members
    bool                m_monitor_run;              // true - unit_test_monitor will be user to monitor running
                                                    // of implementation function
    static bool         s_abort_testing;            // used to flag critical error and try gracefully stop testing
};

//____________________________________________________________________________//

// ************************************************************************** //
// **************              function_test_case              ************** //
// ************************************************************************** //

class function_test_case : public test_case {
public:
    typedef void  (*function_type)();

    // Constructor
    function_test_case( function_type f_, std::string const& name_ )
    : test_case( name_, true, 1 ), m_function( f_ ) {}

protected:
    // test case implementation
    void                do_run()        { m_function(); }

private:
    // Data members
    function_type       m_function;
};

// ************************************************************************** //
// **************                class_test_case               ************** //
// ************************************************************************** //

template<class UserTestCase>
class class_test_case : public test_case {
public:
    typedef void  (UserTestCase::*function_type)();

    // Constructor
    class_test_case( function_type f_, std::string const& name_, boost::shared_ptr<UserTestCase> const& user_test_case_ )
    : test_case( name_, true, 1 ), m_user_test_case( user_test_case_ ), m_function( f_ )
    {}

private:
    // test case implementation
    void                do_run()
    {
        if( (!!m_user_test_case) && m_function )
            ((*m_user_test_case).*m_function)();
    }
    void                do_destroy()
    {
        m_user_test_case.reset(); // t ofree the reference to the shared use test case instance
    }

    // Data members
    boost::shared_ptr<UserTestCase> m_user_test_case;
    function_type       m_function;
};

// ************************************************************************** //
// **************        parametrized_function_test_case       ************** //
// ************************************************************************** //

template <typename ParamIterator, typename ParameterType>
class parametrized_function_test_case : public test_case {
public:
    typedef void  (*function_type)( ParameterType );

    // Constructor
    parametrized_function_test_case( function_type f_, std::string const& name_,
                                     ParamIterator const& par_begin_, ParamIterator const& par_end_ )
    : test_case( name_, true, 0 ), m_first_parameter( par_begin_ ), m_last_parameter( par_end_ ), m_function( f_ )
    {
       // the typecasts are here to keep Borland C++ Builder 5 happy, for other compilers they have no effect:
       p_stages_amount.set( detail::distance( (ParamIterator)par_begin_, (ParamIterator)par_end_ ) );
    }

    // test case implementation
    void                do_init()       { m_curr_parameter = m_first_parameter; }
    void                do_run()        { m_function( *m_curr_parameter++ ); }

private:
    // Data members
    ParamIterator       m_first_parameter;
    ParamIterator       m_last_parameter;
    ParamIterator       m_curr_parameter;

    function_type       m_function;
};

// ************************************************************************** //
// **************         parametrized_class_test_case         ************** //
// ************************************************************************** //

template <class UserTestCase, class ParamIterator, typename ParameterType>
class parametrized_class_test_case : public test_case {
public:
    typedef void  (UserTestCase::*function_type)( ParameterType );

    // Constructor
    parametrized_class_test_case( function_type f_, std::string const& name_, boost::shared_ptr<UserTestCase>const & user_test_case_,
                                  ParamIterator const& par_begin_, ParamIterator const& par_end_ )
    : test_case( name_, true, 0 ), m_first_parameter( par_begin_ ), m_last_parameter( par_end_ ),
      m_user_test_case( user_test_case_ ), m_function( f_ )
    {
       // the typecasts are here to keep Borland C++ Builder 5 happy, for other compilers they have no effect:
       p_stages_amount.set( detail::distance( (ParamIterator)par_begin_, (ParamIterator)par_end_ ) );
    }

    // test case implementation
    void                do_init()       { m_curr_parameter = m_first_parameter; }
    void                do_run()        { ((*m_user_test_case).*m_function)( *m_curr_parameter++ ); }
    void                do_destroy()    { m_user_test_case.reset(); }

private:
    // Data members
    ParamIterator       m_first_parameter;
    ParamIterator       m_last_parameter;
    ParamIterator       m_curr_parameter;

    boost::shared_ptr<UserTestCase> m_user_test_case;
    function_type       m_function;
};

// ************************************************************************** //
// **************                  test_suite                  ************** //
// ************************************************************************** //

class test_suite : public test_case {
public:
    // Constructor
    explicit test_suite( std::string const& name_ = "Master" );

    // Destructor
    virtual             ~test_suite();

    // test case list management
    void                add( test_case* tc_, unit_test_counter expected_failures_ = 0, int timeout_ = 0 );

    // access methods
    unit_test_counter   size() const;

    // test case implementation
    void                do_init();
    void                do_run();

private:
    // Data members
    struct Impl;
    boost::shared_ptr<Impl> m_pimpl;
};

// ************************************************************************** //
// **************               object generators              ************** //
// ************************************************************************** //

namespace detail {

std::string const& normalize_test_case_name( std::string& name_ );

} // namespace detail

//____________________________________________________________________________//

inline test_case*
create_test_case( void (*fct_)(), std::string name_ )
{
    return new function_test_case( fct_, detail::normalize_test_case_name( name_ ) );
}

//____________________________________________________________________________//

template<class UserTestCase>
inline test_case*
create_test_case( void (UserTestCase::*fct_)(), std::string name_, boost::shared_ptr<UserTestCase> const& user_test_case_ )
{
    return new class_test_case<UserTestCase>( fct_, detail::normalize_test_case_name( name_ ), user_test_case_ );
}

//____________________________________________________________________________//

template<typename ParamIterator, typename ParamType>
inline test_case*
create_test_case( void (*fct_)( ParamType ), std::string name_, ParamIterator const& par_begin_, ParamIterator const& par_end_ )
{
    return new parametrized_function_test_case<ParamIterator,ParamType>(
        fct_, detail::normalize_test_case_name( name_ ), par_begin_, par_end_ );
}

//____________________________________________________________________________//

template<class UserTestCase, typename ParamIterator, typename ParamType>
inline test_case*
create_test_case( void (UserTestCase::*fct_)( ParamType ), std::string name_, boost::shared_ptr<UserTestCase> const& user_test_case_,
                  ParamIterator const& par_begin_, ParamIterator const& par_end_ )
{
    return new parametrized_class_test_case<UserTestCase,ParamIterator,ParamType>(
        fct_, detail::normalize_test_case_name( name_ ), user_test_case_, par_begin_, par_end_ );
}

//____________________________________________________________________________//

} // unit_test_framework

} // namespace boost

// ***************************************************************************
//  Revision History :
//
//  $Log$
//  Revision 1.13  2003/02/13 08:23:08  rogeeff
//  C strings eliminated
//  type: virtual method -> property
//  const added to user test case shared instance reference
//
//  Revision 1.12  2002/12/08 17:51:04  rogeeff
//  notion of number of stages is separated from number of test cases, so that
//  parameterized test case in reported as one test case
//  fixed bug in both parameterized function/class test cases with not iterating
//  parameter iterator if exception occured
//  switched to use c_string_literal
//
//  Revision 1.11  2002/11/02 19:31:04  rogeeff
//  merged into the main trank
//

// ***************************************************************************

#endif // BOOST_UNIT_TEST_SUITE_HPP

<commit_msg>methods has_passed and depend_on introduced to manage dependencies<commit_after>//  (C) Copyright Gennadiy Rozental 2001-2003.
//  (C) Copyright Ullrich Koethe 2001.
//  Permission to copy, use, modify, sell and distribute this software
//  is granted provided this copyright notice appears in all copies.
//  This software is provided "as is" without express or implied warranty,
//  and with no claim as to its suitability for any purpose.

//  See http://www.boost.org for most recent version including documentation.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : defines all classes in test_case hierarchy and object generators
//  for them.
// ***************************************************************************

#ifndef BOOST_UNIT_TEST_SUITE_HPP
#define BOOST_UNIT_TEST_SUITE_HPP

// Boost.Test
#include <boost/test/detail/unit_test_monitor.hpp>
#include <boost/test/detail/unit_test_config.hpp>
#include <boost/test/detail/class_properties.hpp>

// BOOST
#include <boost/shared_ptr.hpp>

// STL
#include <string>  // for std::string

//____________________________________________________________________________//

#define BOOST_TEST_CASE( function ) \
boost::unit_test_framework::create_test_case((function), #function )
#define BOOST_CLASS_TEST_CASE( function, tc_instance ) \
boost::unit_test_framework::create_test_case((function), #function, tc_instance )
#define BOOST_PARAM_TEST_CASE( function, begin, end ) \
boost::unit_test_framework::create_test_case((function), #function, (begin), (end) )
#define BOOST_PARAM_CLASS_TEST_CASE( function, tc_instance, begin, end ) \
boost::unit_test_framework::create_test_case((function), #function, tc_instance, (begin), (end) )
#define BOOST_TEST_SUITE( testsuite_name ) \
( new boost::unit_test_framework::test_suite( testsuite_name ) )

namespace boost {

namespace unit_test_framework {

// ************************************************************************** //
// **************                   test_case                  ************** //
// ************************************************************************** //

class test_case {
public:
    typedef detail::unit_test_monitor::error_level error_level_type;

    // post creation configuration
    void                depends_on( test_case const* rhs );

    // Destructor
    virtual             ~test_case()    {}

    // total number of test cases
    virtual unit_test_counter size() const;

    // execute this method to run the test case
    void                run();

    // status
    bool                has_passed() const;

    // public properties
    BOOST_READONLY_PROPERTY( int, 2, (test_case,test_suite) )
                        p_timeout;                  // timeout for the excecution monitor
    BOOST_READONLY_PROPERTY( unit_test_counter, 1, (test_suite) )
                        p_expected_failures;        // number of assertions that are expected to fail in this test case
    BOOST_READONLY_PROPERTY( bool, 0, () )
                        p_type;                     // true = test case, false - test suite
    BOOST_READONLY_PROPERTY( std::string, 0, () )
                        p_name;                     // name for this test case

protected:
    // protected properties
    BOOST_READONLY_PROPERTY( bool, 2, (test_case,test_suite) )
                        p_compound_stage;           // used to properly manage progress report
    BOOST_READWRITE_PROPERTY( unit_test_counter )
                        p_stages_amount;            // number of stages this test consist of; stage could be another test case
                                                    // like with test_suite, another parameterized test for parameterized_test_case
                                                    // or 1 stage that reflect single test_case behaviour

    // access methods
    void                curr_stage_is_compound();

    // Constructor
    explicit            test_case( std::string const&   name_,
                                   bool                 type_,
                                   unit_test_counter    stages_amount_,
                                   bool                 monitor_run_    = true );

    // test case implementation hooks to be called with unit_test_monitor or alone
    virtual void        do_init()       {}
    virtual void        do_run()        {}
    virtual void        do_destroy()    {}

private:
    // Data members
    struct Impl;
    boost::shared_ptr<Impl> m_pimpl;
};

//____________________________________________________________________________//

// ************************************************************************** //
// **************              function_test_case              ************** //
// ************************************************************************** //

class function_test_case : public test_case {
public:
    typedef void  (*function_type)();

    // Constructor
    function_test_case( function_type f_, std::string const& name_ )
    : test_case( name_, true, 1 ), m_function( f_ ) {}

protected:
    // test case implementation
    void                do_run()        { m_function(); }

private:
    // Data members
    function_type       m_function;
};

// ************************************************************************** //
// **************                class_test_case               ************** //
// ************************************************************************** //

template<class UserTestCase>
class class_test_case : public test_case {
public:
    typedef void  (UserTestCase::*function_type)();

    // Constructor
    class_test_case( function_type f_, std::string const& name_, boost::shared_ptr<UserTestCase> const& user_test_case_ )
    : test_case( name_, true, 1 ), m_user_test_case( user_test_case_ ), m_function( f_ )
    {}

private:
    // test case implementation
    void                do_run()
    {
        if( (!!m_user_test_case) && m_function )
            ((*m_user_test_case).*m_function)();
    }
    void                do_destroy()
    {
        m_user_test_case.reset(); // t ofree the reference to the shared use test case instance
    }

    // Data members
    boost::shared_ptr<UserTestCase> m_user_test_case;
    function_type       m_function;
};

// ************************************************************************** //
// **************        parametrized_function_test_case       ************** //
// ************************************************************************** //

template <typename ParamIterator, typename ParameterType>
class parametrized_function_test_case : public test_case {
public:
    typedef void  (*function_type)( ParameterType );

    // Constructor
    parametrized_function_test_case( function_type f_, std::string const& name_,
                                     ParamIterator const& par_begin_, ParamIterator const& par_end_ )
    : test_case( name_, true, 0 ), m_first_parameter( par_begin_ ), m_last_parameter( par_end_ ), m_function( f_ )
    {
       // the typecasts are here to keep Borland C++ Builder 5 happy, for other compilers they have no effect:
       p_stages_amount.set( detail::distance( (ParamIterator)par_begin_, (ParamIterator)par_end_ ) );
    }

    // test case implementation
    void                do_init()       { m_curr_parameter = m_first_parameter; }
    void                do_run()        { m_function( *m_curr_parameter++ ); }

private:
    // Data members
    ParamIterator       m_first_parameter;
    ParamIterator       m_last_parameter;
    ParamIterator       m_curr_parameter;

    function_type       m_function;
};

// ************************************************************************** //
// **************         parametrized_class_test_case         ************** //
// ************************************************************************** //

template <class UserTestCase, class ParamIterator, typename ParameterType>
class parametrized_class_test_case : public test_case {
public:
    typedef void  (UserTestCase::*function_type)( ParameterType );

    // Constructor
    parametrized_class_test_case( function_type f_, std::string const& name_, boost::shared_ptr<UserTestCase>const & user_test_case_,
                                  ParamIterator const& par_begin_, ParamIterator const& par_end_ )
    : test_case( name_, true, 0 ), m_first_parameter( par_begin_ ), m_last_parameter( par_end_ ),
      m_user_test_case( user_test_case_ ), m_function( f_ )
    {
       // the typecasts are here to keep Borland C++ Builder 5 happy, for other compilers they have no effect:
       p_stages_amount.set( detail::distance( (ParamIterator)par_begin_, (ParamIterator)par_end_ ) );
    }

    // test case implementation
    void                do_init()       { m_curr_parameter = m_first_parameter; }
    void                do_run()        { ((*m_user_test_case).*m_function)( *m_curr_parameter++ ); }
    void                do_destroy()    { m_user_test_case.reset(); }

private:
    // Data members
    ParamIterator       m_first_parameter;
    ParamIterator       m_last_parameter;
    ParamIterator       m_curr_parameter;

    boost::shared_ptr<UserTestCase> m_user_test_case;
    function_type       m_function;
};

// ************************************************************************** //
// **************                  test_suite                  ************** //
// ************************************************************************** //

class test_suite : public test_case {
public:
    // Constructor
    explicit test_suite( std::string const& name_ = "Master" );

    // Destructor
    virtual             ~test_suite();

    // test case list management
    void                add( test_case* tc_, unit_test_counter expected_failures_ = 0, int timeout_ = 0 );

    // access methods
    unit_test_counter   size() const;

    // test case implementation
    void                do_init();
    void                do_run();

private:
    // Data members
    struct Impl;
    boost::shared_ptr<Impl> m_pimpl;
};

// ************************************************************************** //
// **************               object generators              ************** //
// ************************************************************************** //

namespace detail {

std::string const& normalize_test_case_name( std::string& name_ );

} // namespace detail

//____________________________________________________________________________//

inline test_case*
create_test_case( void (*fct_)(), std::string name_ )
{
    return new function_test_case( fct_, detail::normalize_test_case_name( name_ ) );
}

//____________________________________________________________________________//

template<class UserTestCase>
inline test_case*
create_test_case( void (UserTestCase::*fct_)(), std::string name_, boost::shared_ptr<UserTestCase> const& user_test_case_ )
{
    return new class_test_case<UserTestCase>( fct_, detail::normalize_test_case_name( name_ ), user_test_case_ );
}

//____________________________________________________________________________//

template<typename ParamIterator, typename ParamType>
inline test_case*
create_test_case( void (*fct_)( ParamType ), std::string name_, ParamIterator const& par_begin_, ParamIterator const& par_end_ )
{
    return new parametrized_function_test_case<ParamIterator,ParamType>(
        fct_, detail::normalize_test_case_name( name_ ), par_begin_, par_end_ );
}

//____________________________________________________________________________//

template<class UserTestCase, typename ParamIterator, typename ParamType>
inline test_case*
create_test_case( void (UserTestCase::*fct_)( ParamType ), std::string name_, boost::shared_ptr<UserTestCase> const& user_test_case_,
                  ParamIterator const& par_begin_, ParamIterator const& par_end_ )
{
    return new parametrized_class_test_case<UserTestCase,ParamIterator,ParamType>(
        fct_, detail::normalize_test_case_name( name_ ), user_test_case_, par_begin_, par_end_ );
}

//____________________________________________________________________________//

} // unit_test_framework

} // namespace boost

// ***************************************************************************
//  Revision History :
//
//  $Log$
//  Revision 1.14  2003/06/09 09:00:09  rogeeff
//  methods has_passed and depend_on introduced to manage dependencies
//

// ***************************************************************************

#endif // BOOST_UNIT_TEST_SUITE_HPP

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkScalarRegionBasedLevelSetFunctionTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkScalarRegionBasedLevelSetFunction.h"
#include "itkVector.h"
#include "itkImage.h"
#include "itkTestingMacros.h"

namespace itk
{

template < class TInput, // LevelSetImageType
  class TFeature, // FeatureImageType
  class TSharedData >
class ScalarRegionBasedLevelSetFunctionTestHelper :
 public ScalarRegionBasedLevelSetFunction< TInput, TFeature, TSharedData >
{
public:
  /** Standard class typedefs. */
  typedef ScalarRegionBasedLevelSetFunctionTestHelper                       Self;
  typedef ScalarRegionBasedLevelSetFunction<TInput,TFeature,TSharedData>    Superclass;
  typedef SmartPointer<Self>                                                Pointer;
  typedef SmartPointer<const Self>                                          ConstPointer;

  itkStaticConstMacro(ImageDimension, unsigned int, Superclass::ImageDimension);

  itkNewMacro(Self);

  /** Run-time type information (and related methods) */
  itkTypeMacro( ScalarRegionBasedLevelSetFunctionTestHelper, ScalarRegionBasedLevelSetFunction );

  typedef typename Superclass::ScalarValueType     ScalarValueType;
  typedef typename Superclass::FeaturePixelType    FeaturePixelType;
  typedef typename Superclass::FeatureIndexType    FeatureIndexType;

  virtual ScalarValueType ComputeInternalTerm(const FeaturePixelType &,
    const FeatureIndexType & )
    {
    return ScalarValueType( 0 );
    }

  virtual ScalarValueType ComputeExternalTerm(const FeaturePixelType &,
    const FeatureIndexType & )
    {
    return ScalarValueType( 0 );
    }

  virtual ScalarValueType ComputeOverlapParameters( const FeatureIndexType& ,
    ScalarValueType& )
    {
    return ScalarValueType( 0 );
    }

  virtual void ComputeParameters() {}

  virtual void UpdateSharedDataParameters() {}

  virtual void UpdateSharedDataInsideParameters( const unsigned int& ,
    const bool& , const FeaturePixelType&, const ScalarValueType& ) {}

  virtual void UpdateSharedDataOutsideParameters( const unsigned int& ,
    const bool& , const FeaturePixelType&, const ScalarValueType& ) {}

protected:
  ScalarRegionBasedLevelSetFunctionTestHelper() {}
  ~ScalarRegionBasedLevelSetFunctionTestHelper() {}

private:
  ScalarRegionBasedLevelSetFunctionTestHelper(const Self&); //purposely not implemented
  void operator=(const Self&); //purposely not implemented
};

template <unsigned int NDimension>
class ScalarRegionBasedLevelSetFunctionSharedDataHelper : public DataObject
{
public:
  /** Standard class typedefs. */
  typedef ScalarRegionBasedLevelSetFunctionSharedDataHelper   Self;
  typedef DataObject                                          Superclass;
  typedef SmartPointer<Self>                                  Pointer;
  typedef SmartPointer<const Self>                            ConstPointer;

  itkNewMacro(Self);

  /** Run-time type information (and related methods) */
  itkTypeMacro( ScalarRegionBasedLevelSetFunctionSharedDataHelper, DataObject );

  unsigned long       m_FunctionCount;

  typedef Index< NDimension >                 IndexType;
  typedef std::list< unsigned int >           ListPixelType;

  typedef Image< ListPixelType, NDimension > ImageType;
  typename ImageType::Pointer   m_NearestNeighborListImage;

  typedef double                              PixelType;
  typedef Image< PixelType, NDimension >      InputImageType;

  struct SingleData
    {
    typename InputImageType::Pointer m_HeavisideFunctionOfLevelSetImage;
    int m_WeightedNumberOfPixelsInsideLevelSet;
    int m_WeightedSumOfPixelValuesInsideLevelSet;
    int m_ForegroundConstantValues;

    int m_WeightedNumberOfPixelsOutsideLevelSet;
    int m_WeightedSumOfPixelValuesOutsideLevelSet;
    int m_BackgroundConstantValues;

    IndexType GetFeatureIndex( const IndexType & indx )
      {
      return indx;
      }

    IndexType GetIndex( const IndexType & globalIndex )
      {
      return globalIndex;
      }
    };

  SingleData* m_LevelSetDataPointerVector[19];

};

}

int itkScalarRegionBasedLevelSetFunctionTest( int, char* [] )
{
  const unsigned int Dimension = 3;

  typedef double                                  PixelType;
  typedef itk::Image< PixelType, Dimension >      ImageType;
  typedef itk::Image< float, Dimension >          FeatureImageType;

  typedef itk::ScalarRegionBasedLevelSetFunctionSharedDataHelper<Dimension>      DataHelperType;

  typedef itk::ScalarRegionBasedLevelSetFunctionTestHelper<
    ImageType, FeatureImageType, DataHelperType >      RegionBasedLevelSetFunctionType;

  RegionBasedLevelSetFunctionType::Pointer function = RegionBasedLevelSetFunctionType::New();

  return EXIT_SUCCESS;
}
<commit_msg>ENH: Changed the API of the methods UpdateSharedDataInsideParameters() and UpdateSharedDataOutsideParameters()<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkScalarRegionBasedLevelSetFunctionTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkScalarRegionBasedLevelSetFunction.h"
#include "itkVector.h"
#include "itkImage.h"
#include "itkTestingMacros.h"

namespace itk
{

template < class TInput, // LevelSetImageType
  class TFeature, // FeatureImageType
  class TSharedData >
class ScalarRegionBasedLevelSetFunctionTestHelper :
 public ScalarRegionBasedLevelSetFunction< TInput, TFeature, TSharedData >
{
public:
  /** Standard class typedefs. */
  typedef ScalarRegionBasedLevelSetFunctionTestHelper                       Self;
  typedef ScalarRegionBasedLevelSetFunction<TInput,TFeature,TSharedData>    Superclass;
  typedef SmartPointer<Self>                                                Pointer;
  typedef SmartPointer<const Self>                                          ConstPointer;

  itkStaticConstMacro(ImageDimension, unsigned int, Superclass::ImageDimension);

  itkNewMacro(Self);

  /** Run-time type information (and related methods) */
  itkTypeMacro( ScalarRegionBasedLevelSetFunctionTestHelper, ScalarRegionBasedLevelSetFunction );

  typedef typename Superclass::ScalarValueType     ScalarValueType;
  typedef typename Superclass::FeaturePixelType    FeaturePixelType;
  typedef typename Superclass::FeatureIndexType    FeatureIndexType;

  virtual ScalarValueType ComputeInternalTerm(const FeaturePixelType &,
    const FeatureIndexType & )
    {
    return ScalarValueType( 0 );
    }

  virtual ScalarValueType ComputeExternalTerm(const FeaturePixelType &,
    const FeatureIndexType & )
    {
    return ScalarValueType( 0 );
    }

  virtual ScalarValueType ComputeOverlapParameters( const FeatureIndexType& ,
    ScalarValueType& )
    {
    return ScalarValueType( 0 );
    }

  virtual void ComputeParameters() {}

  virtual void UpdateSharedDataParameters() {}

  virtual void UpdateSharedDataInsideParameters( const unsigned int& ,
    const FeaturePixelType&, const ScalarValueType& ) {}

  virtual void UpdateSharedDataOutsideParameters( const unsigned int& ,
    const FeaturePixelType&, const ScalarValueType& ) {}

protected:
  ScalarRegionBasedLevelSetFunctionTestHelper() {}
  ~ScalarRegionBasedLevelSetFunctionTestHelper() {}

private:
  ScalarRegionBasedLevelSetFunctionTestHelper(const Self&); //purposely not implemented
  void operator=(const Self&); //purposely not implemented
};

template <unsigned int NDimension>
class ScalarRegionBasedLevelSetFunctionSharedDataHelper : public DataObject
{
public:
  /** Standard class typedefs. */
  typedef ScalarRegionBasedLevelSetFunctionSharedDataHelper   Self;
  typedef DataObject                                          Superclass;
  typedef SmartPointer<Self>                                  Pointer;
  typedef SmartPointer<const Self>                            ConstPointer;

  itkNewMacro(Self);

  /** Run-time type information (and related methods) */
  itkTypeMacro( ScalarRegionBasedLevelSetFunctionSharedDataHelper, DataObject );

  unsigned long       m_FunctionCount;

  typedef Index< NDimension >                 IndexType;
  typedef std::list< unsigned int >           ListPixelType;

  typedef Image< ListPixelType, NDimension > ImageType;
  typename ImageType::Pointer   m_NearestNeighborListImage;

  typedef double                              PixelType;
  typedef Image< PixelType, NDimension >      InputImageType;

  struct SingleData
    {
    typename InputImageType::Pointer m_HeavisideFunctionOfLevelSetImage;
    int m_WeightedNumberOfPixelsInsideLevelSet;
    int m_WeightedSumOfPixelValuesInsideLevelSet;
    int m_ForegroundConstantValues;

    int m_WeightedNumberOfPixelsOutsideLevelSet;
    int m_WeightedSumOfPixelValuesOutsideLevelSet;
    int m_BackgroundConstantValues;

    IndexType GetFeatureIndex( const IndexType & indx )
      {
      return indx;
      }

    IndexType GetIndex( const IndexType & globalIndex )
      {
      return globalIndex;
      }
    };

  SingleData* m_LevelSetDataPointerVector[19];

};

}

int itkScalarRegionBasedLevelSetFunctionTest( int, char* [] )
{
  const unsigned int Dimension = 3;

  typedef double                                  PixelType;
  typedef itk::Image< PixelType, Dimension >      ImageType;
  typedef itk::Image< float, Dimension >          FeatureImageType;

  typedef itk::ScalarRegionBasedLevelSetFunctionSharedDataHelper<Dimension>      DataHelperType;

  typedef itk::ScalarRegionBasedLevelSetFunctionTestHelper<
    ImageType, FeatureImageType, DataHelperType >      RegionBasedLevelSetFunctionType;

  RegionBasedLevelSetFunctionType::Pointer function = RegionBasedLevelSetFunctionType::New();

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#pragma once

/*
 * Factories for variable names. The key feature of a variable name is
 * that it can be indexed in a datastructure such as patricia trees by
 * providing the method index().
 */

#include <crab/support/debug.hpp>
#include <crab/support/os.hpp>
#include <crab/types/indexable.hpp>

#include <boost/optional.hpp>
#include <boost/range/iterator_range.hpp>

#include <functional>
#include <limits>
#include <map>
#include <memory>
#include <unordered_map>
#include <vector>

namespace crab {

/* T is the template parameter of var_factory_impl::variable_factory */
template <typename T> class variable_name_traits {
public:
  static std::string to_string(T varname);
};

namespace var_factory_impl {

template <typename T> class variable_factory;

template <class T> class indexed_varname : public indexable {
  template <typename Any> friend class variable_factory;

  using this_type = indexed_varname<T>;
  using variable_factory_t = variable_factory<T>;

  boost::optional<T> m_s;
  ikos::index_t m_id;
  // optional string name associated with m_id if m_s is boost::none
  std::shared_ptr<std::string> m_name;
  variable_factory_t *m_vfac;

  indexed_varname() = delete;
  // first constructor
  indexed_varname(ikos::index_t id, variable_factory_t *vfac,
                  std::string name = "")
      : m_s(boost::none), m_id(id),
        m_name(name == "" ? nullptr : std::make_shared<std::string>(name)),
        m_vfac(vfac) {}
  // second constructor
  indexed_varname(T s, ikos::index_t id, variable_factory_t *vfac)
      : m_s(s), m_id(id), m_name(nullptr), m_vfac(vfac) {}

  std::string rename(const std::string &s) const {
    auto it = m_vfac->get_renaming_map().find(s);
    if (it != m_vfac->get_renaming_map().end()) {
      return it->second;
    } else {
      return s;
    }
  }

public:
  indexed_varname(const this_type &is) = default;
  indexed_varname(this_type &&is) = default;
  ~indexed_varname() = default;
  this_type &operator=(const this_type &is) = default;
  this_type &operator=(this_type &&is) = default;

  virtual ikos::index_t index() const override { return m_id; }

  std::string str() const {
    if (m_s) {
      return rename(crab::variable_name_traits<T>::to_string(*m_s));
    } else if (m_name && (*m_name != "")) {
      return rename(*m_name);
    } else {
      // unlikely prefix
      return rename("@V_" + std::to_string(m_id));
    }
  }

  boost::optional<T> get() const { return m_s; }

  variable_factory_t &get_var_factory() { return *m_vfac; }

  bool operator<(const this_type &s) const { return (m_id < s.m_id); }

  bool operator==(const this_type &s) const { return (m_id == s.m_id); }

  virtual void write(crab_os &o) const override { o << str(); }

  size_t hash() const {
    std::hash<ikos::index_t> hasher;
    return hasher(index());
  }

  friend crab_os &operator<<(crab_os &o, const this_type &s) {
    s.write(o);
    return o;
  }

};
// used by boost::hash_combine (no std::hash_combine in C+11)
//template <typename T>
//inline std::size_t hash_value(const crab::var_factory_impl::indexed_varname<T>&v) {
//  return v.hash();
//}
} // end namespace var_factory_impl
} // end namespace crab

namespace std {
template <typename T> struct hash<crab::var_factory_impl::indexed_varname<T>> {
  size_t operator()(
      const typename crab::var_factory_impl::indexed_varname<T> &v) const {
    return v.hash();
  }
};
} // end namespace std

namespace crab {
namespace var_factory_impl {

// This variable factory (it's actually a factory of
// indexed_varname's) creates a new indexed_variable associated to an
// element of type T if provided. It can also create indexed_varname's
// that are not associated to an element of type T. We call them
// shadow variables.
//
// The factory uses a counter of type index_t to generate variable
// id's that always increases.
template <class T> class variable_factory {
  using variable_factory_t = variable_factory<T>;
  using t_map_t = std::unordered_map<T, indexed_varname<T>>;
  using shadow_map_t =
      std::unordered_map<indexed_varname<T>,
                         std::map<std::string, indexed_varname<T>>>;
  // global counter to generate indexes
  ikos::index_t m_next_id;
  // (cached) indexed_varname's associated with a T-instance.
  t_map_t m_map;
  // (non-cached) fresh indexed_varname's.
  std::vector<indexed_varname<T>> m_shadow_vars;
  // (cached) indexed_varname's associated with another indexed_varname.
  shadow_map_t m_shadow_map;
  mutable std::unordered_map<std::string, std::string> m_renaming_map;

  ikos::index_t get_and_increment_id(void) {
    if (m_next_id == std::numeric_limits<ikos::index_t>::max()) {
      CRAB_ERROR("Reached limit of ", std::numeric_limits<ikos::index_t>::max(),
                 " variables");
    }
    ikos::index_t res = m_next_id;
    ++m_next_id;
    return res;
  }

public:
  using varname_t = indexed_varname<T>;

  variable_factory() : m_next_id(1) {}

  virtual ~variable_factory() = default;

  variable_factory(ikos::index_t start_id) : m_next_id(start_id) {}

  variable_factory(const variable_factory_t &o) = delete;

  variable_factory_t &operator=(const variable_factory_t &o) = delete;

  virtual varname_t operator[](T s) {
    auto it = m_map.find(s);
    if (it == m_map.end()) {
      varname_t iv(s, get_and_increment_id(), this);
      m_map.insert({s, iv});
      return iv;
    } else {
      return it->second;
    }
  }

  // Generate a fresh indexed_varname's without being associated with
  // a particular instance of T.
  //
  // If you are an abstract domain then do not use it unless strictly
  // necessary because it can produce an unbounded number of
  // indexed_varname objects.
  virtual varname_t get(std::string name = "") {
    varname_t iv(get_and_increment_id(), this, name);
    m_shadow_vars.push_back(iv);
    return iv;
  }

  // API for abstract domains
  //
  // Create a fresh indexed_varname associated to var.
  // Given the same var and name it always return the same indexed_varname.
  // The returned indexed_varname's name is var's name concatenated with name.
  virtual varname_t get(const varname_t &var, std::string name) {
    auto it = m_shadow_map.find(var);
    if (it == m_shadow_map.end()) {
      varname_t iv(get_and_increment_id(), this, var.str() + name);
      std::map<std::string, varname_t> named_shadows;
      named_shadows.insert({name, iv});
      m_shadow_map.insert({var, named_shadows});
      return iv;
    } else {
      std::map<std::string, varname_t> &named_shadows = it->second;
      auto nit = named_shadows.find(name);
      if (nit != named_shadows.end()) {
        return nit->second;
      } else {
        varname_t iv(get_and_increment_id(), this, var.str() + name);
        named_shadows.insert({name, iv});
        return iv;
      }
    }
  }

  // Allow temporary renaming for pretty printing
  void add_renaming_map(
      const std::unordered_map<std::string, std::string> &smap) const {
    clear_renaming_map();
    m_renaming_map.insert(smap.begin(), smap.end());
  }

  void clear_renaming_map() const { m_renaming_map.clear(); }

  const std::unordered_map<std::string, std::string> &get_renaming_map() const {
    return m_renaming_map;
  }

  // return all the non-T variables created by the factory.
  virtual std::vector<varname_t> get_shadow_vars() const {
    std::vector<varname_t> out(m_shadow_vars.begin(), m_shadow_vars.end());
    for (auto &kv_ : m_shadow_map) {
      for (auto &kv : kv_.second) {
        out.push_back(varname_t(kv.second));
      }
    }
    return out;
  }
};

//! Specialized factory for strings
class str_variable_factory : public variable_factory<std::string> {
  using variable_factory_t = variable_factory<std::string>;

public:
  using varname_t = typename variable_factory_t::varname_t;

  str_variable_factory() : variable_factory_t() {}
};

inline int fresh_colour(int col_x, int col_y) {
  switch (col_x) {
  case 0:
    return col_y == 1 ? 2 : 1;
  case 1:
    return col_y == 0 ? 2 : 0;
  case 2:
    return col_y == 0 ? 1 : 0;
  default:
    CRAB_ERROR("Unreachable");
  }
}

//! Three-coloured variable allocation. So the number of variables
//  is bounded by 3|Tbl|, rather than always increasing.
class str_var_alloc_col {
  static const char **col_prefix;

  // Ideally, str_var_alloc_col should inherit from
  // str_variable_factory.  However, we need public copy constructors
  // for str_var_alloc_col. The hack here is to have vfac as a global
  // factory that all str_var_alloc_col's share.
  static str_variable_factory &get_vfac() {
    static str_variable_factory vfac;
    return vfac;
  }

public:
  using varname_t = str_variable_factory::varname_t;

  str_var_alloc_col() : colour(0), next_id(0) {}

  str_var_alloc_col(const str_var_alloc_col &o)
      : colour(o.colour), next_id(o.next_id) {}

  str_var_alloc_col(const str_var_alloc_col &x, const str_var_alloc_col &y)
      : colour(fresh_colour(x.colour, y.colour)), next_id(0) {
    assert(colour != x.colour);
    assert(colour != y.colour);
  }

  str_var_alloc_col &operator=(const str_var_alloc_col &x) {
    if (this != &x) {
      colour = x.colour;
      next_id = x.next_id;
    }
    return *this;
  }

  str_variable_factory::varname_t next() {
    std::string v = col_prefix[colour] + std::to_string(next_id++);
    return get_vfac()[v];
  }

  void add_renaming_map(
      const std::unordered_map<std::string, std::string> &smap) const {
    get_vfac().add_renaming_map(smap);
  }

  void clear_renaming_map() const { get_vfac().clear_renaming_map(); }

protected:
  int colour;
  ikos::index_t next_id;
};

//// The type ikos::index_t cannot be used directly as varname_t. We
//// need a wrapper that implements index() function.
// //! Specialized factory for integers
// class int_variable_factory {
// public:
//   using varname_t = ikos::index_t;
//   int_variable_factory() {}
//   int_variable_factory(const int_variable_factory &o) = delete;
//   int_variable_factory &operator=(const int_variable_factory &o) = delete;
//   varname_t operator[](ikos::index_t v) { return v; }
// };
// class int_var_alloc_col {
// public:
//   using varname_t = ikos::index_t;
//   static int_variable_factory vfac;
//   int_var_alloc_col() : colour(0), next_id(0) {}
//   int_var_alloc_col(const int_var_alloc_col &o)
//       : colour(o.colour), next_id(o.next_id) {}
//   int_var_alloc_col(const int_var_alloc_col &x, const int_var_alloc_col &y)
//       : colour(fresh_colour(x.colour, y.colour)), next_id(0) {
//     assert(colour != x.colour);
//     assert(colour != y.colour);
//   }
//   int_var_alloc_col &operator=(const int_var_alloc_col &x) {
//     colour = x.colour;
//     next_id = x.next_id;
//     return *this;
//   }
//   int_variable_factory::varname_t next() {
//     ikos::index_t id = next_id++;
//     return 3 * id + colour;
//   }
// protected:
//   int colour;
//   ikos::index_t next_id;
// };

} // end namespace var_factory_impl
} // end namespace crab
<commit_msg>fix: expose typedef<commit_after>#pragma once

/*
 * Factories for variable names. The key feature of a variable name is
 * that it can be indexed in a datastructure such as patricia trees by
 * providing the method index().
 */

#include <crab/support/debug.hpp>
#include <crab/support/os.hpp>
#include <crab/types/indexable.hpp>

#include <boost/optional.hpp>
#include <boost/range/iterator_range.hpp>

#include <functional>
#include <limits>
#include <map>
#include <memory>
#include <unordered_map>
#include <vector>

namespace crab {

/* T is the template parameter of var_factory_impl::variable_factory */
template <typename T> class variable_name_traits {
public:
  static std::string to_string(T varname);
};

namespace var_factory_impl {

template <typename T> class variable_factory;

template <class T> class indexed_varname : public indexable {
  template <typename Any> friend class variable_factory;
public:
  using variable_factory_t = variable_factory<T>;

private:
  using this_type = indexed_varname<T>;

  boost::optional<T> m_s;
  ikos::index_t m_id;
  // optional string name associated with m_id if m_s is boost::none
  std::shared_ptr<std::string> m_name;
  variable_factory_t *m_vfac;

  indexed_varname() = delete;
  // first constructor
  indexed_varname(ikos::index_t id, variable_factory_t *vfac,
                  std::string name = "")
      : m_s(boost::none), m_id(id),
        m_name(name == "" ? nullptr : std::make_shared<std::string>(name)),
        m_vfac(vfac) {}
  // second constructor
  indexed_varname(T s, ikos::index_t id, variable_factory_t *vfac)
      : m_s(s), m_id(id), m_name(nullptr), m_vfac(vfac) {}

  std::string rename(const std::string &s) const {
    auto it = m_vfac->get_renaming_map().find(s);
    if (it != m_vfac->get_renaming_map().end()) {
      return it->second;
    } else {
      return s;
    }
  }

public:
  indexed_varname(const this_type &is) = default;
  indexed_varname(this_type &&is) = default;
  ~indexed_varname() = default;
  this_type &operator=(const this_type &is) = default;
  this_type &operator=(this_type &&is) = default;

  virtual ikos::index_t index() const override { return m_id; }

  std::string str() const {
    if (m_s) {
      return rename(crab::variable_name_traits<T>::to_string(*m_s));
    } else if (m_name && (*m_name != "")) {
      return rename(*m_name);
    } else {
      // unlikely prefix
      return rename("@V_" + std::to_string(m_id));
    }
  }

  boost::optional<T> get() const { return m_s; }

  variable_factory_t &get_var_factory() { return *m_vfac; }

  bool operator<(const this_type &s) const { return (m_id < s.m_id); }

  bool operator==(const this_type &s) const { return (m_id == s.m_id); }

  virtual void write(crab_os &o) const override { o << str(); }

  size_t hash() const {
    std::hash<ikos::index_t> hasher;
    return hasher(index());
  }

  friend crab_os &operator<<(crab_os &o, const this_type &s) {
    s.write(o);
    return o;
  }

};
// used by boost::hash_combine (no std::hash_combine in C+11)
//template <typename T>
//inline std::size_t hash_value(const crab::var_factory_impl::indexed_varname<T>&v) {
//  return v.hash();
//}
} // end namespace var_factory_impl
} // end namespace crab

namespace std {
template <typename T> struct hash<crab::var_factory_impl::indexed_varname<T>> {
  size_t operator()(
      const typename crab::var_factory_impl::indexed_varname<T> &v) const {
    return v.hash();
  }
};
} // end namespace std

namespace crab {
namespace var_factory_impl {

// This variable factory (it's actually a factory of
// indexed_varname's) creates a new indexed_variable associated to an
// element of type T if provided. It can also create indexed_varname's
// that are not associated to an element of type T. We call them
// shadow variables.
//
// The factory uses a counter of type index_t to generate variable
// id's that always increases.
template <class T> class variable_factory {
  using variable_factory_t = variable_factory<T>;
  using t_map_t = std::unordered_map<T, indexed_varname<T>>;
  using shadow_map_t =
      std::unordered_map<indexed_varname<T>,
                         std::map<std::string, indexed_varname<T>>>;
  // global counter to generate indexes
  ikos::index_t m_next_id;
  // (cached) indexed_varname's associated with a T-instance.
  t_map_t m_map;
  // (non-cached) fresh indexed_varname's.
  std::vector<indexed_varname<T>> m_shadow_vars;
  // (cached) indexed_varname's associated with another indexed_varname.
  shadow_map_t m_shadow_map;
  mutable std::unordered_map<std::string, std::string> m_renaming_map;

  ikos::index_t get_and_increment_id(void) {
    if (m_next_id == std::numeric_limits<ikos::index_t>::max()) {
      CRAB_ERROR("Reached limit of ", std::numeric_limits<ikos::index_t>::max(),
                 " variables");
    }
    ikos::index_t res = m_next_id;
    ++m_next_id;
    return res;
  }

public:
  using varname_t = indexed_varname<T>;

  variable_factory() : m_next_id(1) {}

  virtual ~variable_factory() = default;

  variable_factory(ikos::index_t start_id) : m_next_id(start_id) {}

  variable_factory(const variable_factory_t &o) = delete;

  variable_factory_t &operator=(const variable_factory_t &o) = delete;

  virtual varname_t operator[](T s) {
    auto it = m_map.find(s);
    if (it == m_map.end()) {
      varname_t iv(s, get_and_increment_id(), this);
      m_map.insert({s, iv});
      return iv;
    } else {
      return it->second;
    }
  }

  // Generate a fresh indexed_varname's without being associated with
  // a particular instance of T.
  //
  // If you are an abstract domain then do not use it unless strictly
  // necessary because it can produce an unbounded number of
  // indexed_varname objects.
  virtual varname_t get(std::string name = "") {
    varname_t iv(get_and_increment_id(), this, name);
    m_shadow_vars.push_back(iv);
    return iv;
  }

  // API for abstract domains
  //
  // Create a fresh indexed_varname associated to var.
  // Given the same var and name it always return the same indexed_varname.
  // The returned indexed_varname's name is var's name concatenated with name.
  virtual varname_t get(const varname_t &var, std::string name) {
    auto it = m_shadow_map.find(var);
    if (it == m_shadow_map.end()) {
      varname_t iv(get_and_increment_id(), this, var.str() + name);
      std::map<std::string, varname_t> named_shadows;
      named_shadows.insert({name, iv});
      m_shadow_map.insert({var, named_shadows});
      return iv;
    } else {
      std::map<std::string, varname_t> &named_shadows = it->second;
      auto nit = named_shadows.find(name);
      if (nit != named_shadows.end()) {
        return nit->second;
      } else {
        varname_t iv(get_and_increment_id(), this, var.str() + name);
        named_shadows.insert({name, iv});
        return iv;
      }
    }
  }

  // Allow temporary renaming for pretty printing
  void add_renaming_map(
      const std::unordered_map<std::string, std::string> &smap) const {
    clear_renaming_map();
    m_renaming_map.insert(smap.begin(), smap.end());
  }

  void clear_renaming_map() const { m_renaming_map.clear(); }

  const std::unordered_map<std::string, std::string> &get_renaming_map() const {
    return m_renaming_map;
  }

  // return all the non-T variables created by the factory.
  virtual std::vector<varname_t> get_shadow_vars() const {
    std::vector<varname_t> out(m_shadow_vars.begin(), m_shadow_vars.end());
    for (auto &kv_ : m_shadow_map) {
      for (auto &kv : kv_.second) {
        out.push_back(varname_t(kv.second));
      }
    }
    return out;
  }
};

//! Specialized factory for strings
class str_variable_factory : public variable_factory<std::string> {
  using variable_factory_t = variable_factory<std::string>;

public:
  using varname_t = typename variable_factory_t::varname_t;

  str_variable_factory() : variable_factory_t() {}
};

inline int fresh_colour(int col_x, int col_y) {
  switch (col_x) {
  case 0:
    return col_y == 1 ? 2 : 1;
  case 1:
    return col_y == 0 ? 2 : 0;
  case 2:
    return col_y == 0 ? 1 : 0;
  default:
    CRAB_ERROR("Unreachable");
  }
}

//! Three-coloured variable allocation. So the number of variables
//  is bounded by 3|Tbl|, rather than always increasing.
class str_var_alloc_col {
  static const char **col_prefix;

  // Ideally, str_var_alloc_col should inherit from
  // str_variable_factory.  However, we need public copy constructors
  // for str_var_alloc_col. The hack here is to have vfac as a global
  // factory that all str_var_alloc_col's share.
  static str_variable_factory &get_vfac() {
    static str_variable_factory vfac;
    return vfac;
  }

public:
  using varname_t = str_variable_factory::varname_t;

  str_var_alloc_col() : colour(0), next_id(0) {}

  str_var_alloc_col(const str_var_alloc_col &o)
      : colour(o.colour), next_id(o.next_id) {}

  str_var_alloc_col(const str_var_alloc_col &x, const str_var_alloc_col &y)
      : colour(fresh_colour(x.colour, y.colour)), next_id(0) {
    assert(colour != x.colour);
    assert(colour != y.colour);
  }

  str_var_alloc_col &operator=(const str_var_alloc_col &x) {
    if (this != &x) {
      colour = x.colour;
      next_id = x.next_id;
    }
    return *this;
  }

  str_variable_factory::varname_t next() {
    std::string v = col_prefix[colour] + std::to_string(next_id++);
    return get_vfac()[v];
  }

  void add_renaming_map(
      const std::unordered_map<std::string, std::string> &smap) const {
    get_vfac().add_renaming_map(smap);
  }

  void clear_renaming_map() const { get_vfac().clear_renaming_map(); }

protected:
  int colour;
  ikos::index_t next_id;
};

//// The type ikos::index_t cannot be used directly as varname_t. We
//// need a wrapper that implements index() function.
// //! Specialized factory for integers
// class int_variable_factory {
// public:
//   using varname_t = ikos::index_t;
//   int_variable_factory() {}
//   int_variable_factory(const int_variable_factory &o) = delete;
//   int_variable_factory &operator=(const int_variable_factory &o) = delete;
//   varname_t operator[](ikos::index_t v) { return v; }
// };
// class int_var_alloc_col {
// public:
//   using varname_t = ikos::index_t;
//   static int_variable_factory vfac;
//   int_var_alloc_col() : colour(0), next_id(0) {}
//   int_var_alloc_col(const int_var_alloc_col &o)
//       : colour(o.colour), next_id(o.next_id) {}
//   int_var_alloc_col(const int_var_alloc_col &x, const int_var_alloc_col &y)
//       : colour(fresh_colour(x.colour, y.colour)), next_id(0) {
//     assert(colour != x.colour);
//     assert(colour != y.colour);
//   }
//   int_var_alloc_col &operator=(const int_var_alloc_col &x) {
//     colour = x.colour;
//     next_id = x.next_id;
//     return *this;
//   }
//   int_variable_factory::varname_t next() {
//     ikos::index_t id = next_id++;
//     return 3 * id + colour;
//   }
// protected:
//   int colour;
//   ikos::index_t next_id;
// };

} // end namespace var_factory_impl
} // end namespace crab
<|endoftext|>