<commit_before>/**
 * A worst-case O(N) time algorithm for the
 * total variation filter problem in one dimension.
 */

#include <vector>
#include <deque>

namespace tvf
{

namespace detail
{

struct Point
{
  double x;
  double y;

  void operator+= (const Point &rhs)
  {
    x += rhs.x;
    y += rhs.y;
  }

  void operator-= (const Point &rhs)
  {
    x -= rhs.x;
    y -= rhs.y;
  }
};

inline double inner_product (const Point &u, const Point &v)
{
  return u.x * v.y - u.y * v.x;
}

/*
 * Add point on the right of convex/concave chain
 * removing all points not in the convex hull of the
 * new set.
 */
template<typename Q, typename Dot>
void convex_chain_extend (Q &chain, Point p, const Dot &dot)
{
  while (!chain.empty () && dot (p, chain.back ()) <= 0.)
  {
    p += chain.back ();
    chain.pop_back ();
  }

  chain.push_back (p);
}

template<typename InputIt, typename Dot>
InputIt
convex_chain_reduce (Point &p,
		     InputIt chain_begin,
		     const InputIt &chain_end,
		     const Dot &dot)
{
  Point v {0., 0.};
  for (; chain_begin != chain_end; ++chain_begin)
  {
    auto next_v = v;
    next_v += *chain_begin;

    if (dot (p, next_v) > 0)
    {
      break;
    }

    v = next_v;
  }

  p -= v;
  return chain_begin;
}

} // namespace detail {

template<typename InputIt, typename OutIt>
OutIt total_variation_filter (InputIt first,
			      InputIt last,
			      const double lambda,
			      OutIt output)
{
  using namespace detail;

  /*
   * Geodesics to upper/lower bounding chains
   */
  std::deque<Point> upper;
  std::deque<Point> lower;

  /*
   * Handle input of length <= 1 separately
   */
  if (first == last)
  {
    return output;
  }

  if (std::distance (first, last) == 1)
  {
    *output++ = *first;
    return output;
  }
  else
  {
    const auto v = *first++;
    upper.push_back ({v + lambda/2, 1});
    lower.push_back ({v - lambda/2, 1});
  }

  /*
   * Logic to update upper/lower geodesics
   */
  const auto update = [&] (
    auto &u, auto &l, const Point &p, auto &&dot)
  {
    convex_chain_extend (u, p, dot);

    if (u.size () == 1 && !l.empty ())
    {
      const auto nf = convex_chain_reduce (
        u.front (), l.begin (), l.end (), dot);

      if (nf != l.begin ())
      {
	for (auto it = l.begin (); it != nf; ++it)
	{
	  output = std::fill_n (output, it->y, it->x / it->y);
	}

	l.erase (l.begin (), nf);
      }
    }
  };

  for (;;)
  {
    const auto value = *first++;
    const bool is_last = (first == last);

    const Point p {is_last ? (value - lambda / 2) : value, 1};

    update (upper, lower, p, inner_product);

    if (is_last)
    {
      for (const auto &p : upper)
      {
	output = std::fill_n (output, p.y, p.x / p.y);
      }

      return output;
    }
    else
    {
      update (lower, upper, p, [] (auto &&x, auto &&y)
      {
	return inner_product (y, x);
      });
    }
  }

  return output;
}

} // namespace tvf {
<commit_msg>Fixed logic of lower geodesic update<commit_after>/**
 * A worst-case O(N) time algorithm for the
 * total variation filter problem in one dimension.
 */

#include <vector>
#include <deque>

namespace tvf
{

/**
 * Calculate total variation denoised (filtered) values of
 * the input range [@p first, @last) with TV penalty lambda.
 * Write output values in @output.
 */
template<typename FwdIt, typename OutIt>
OutIt total_variation_filter (
  FwdIt first,   FwdIt last,
  double lambda, OutIt output);

/*************************************************
 *
 * Inlined implementation
 *
 *************************************************/
namespace detail
{

struct Point
{
  double x;
  double y;

  void operator+= (const Point &rhs)
  {
    x += rhs.x;
    y += rhs.y;
  }

  void operator-= (const Point &rhs)
  {
    x -= rhs.x;
    y -= rhs.y;
  }
};

inline double inner_product (const Point &u, const Point &v)
{
  return u.x * v.y - u.y * v.x;
}

/*
 * Add point on the right of convex/concave chain
 * removing all points not in the convex hull of the
 * new set.
 */
template<typename Q, typename Dot>
void convex_chain_extend (Q &chain, Point p, const Dot &dot)
{
  while (!chain.empty () && dot (p, chain.back ()) <= 0.)
  {
    p += chain.back ();
    chain.pop_back ();
  }

  chain.push_back (p);
}

/*
 * Symmetric
 */
template<typename InputIt, typename Dot>
InputIt
convex_chain_reduce (Point &p,
		     InputIt chain_begin,
		     const InputIt &chain_end,
		     const Dot &dot)
{
  while (chain_begin != chain_end &&
	 dot (p, *chain_begin) < 0)
  {
    p -= *chain_begin;
    ++chain_begin;
  }

  return chain_begin;
}

} // namespace detail {

template<typename InputIt, typename OutIt>
OutIt total_variation_filter (InputIt first,
			      InputIt last,
			      const double lambda,
			      OutIt output)
{
  using namespace detail;

  /*
   * Geodesics to upper/lower bounding chains
   */
  std::deque<Point> upper;
  std::deque<Point> lower;

  /*
   * Handle input of length <= 1 separately
   */
  if (first == last)
  {
    return output;
  }
  if (first + 1 == last)
  {
    *output++ = *first;
    return output;
  }
  else
  {
    const auto v = *first++;
    upper.push_back ({v + lambda/2, 1});
    lower.push_back ({v - lambda/2, 1});
  }

  /*
   * Logic to update upper/lower geodesics
   */
  const auto update = [&] (
    auto &u, auto &l, const Point &p, auto &&dot)
  {
    convex_chain_extend (u, p, dot);

    if (u.size () == 1 && !l.empty ())
    {
      const auto nf = convex_chain_reduce (
        u.front (), l.begin (), l.end (), dot);

      if (nf != l.begin ())
      {
	for (auto it = l.begin (); it != nf; ++it)
	{
	  output = std::fill_n (output, it->y, it->x / it->y);
	}

	l.erase (l.begin (), nf);
      }
    }
  };

  for (;;)
  {
    const auto value = *first++;
    const bool is_last = (first == last);

    const Point p {is_last ? (value - lambda / 2) : value, 1};

    update (upper, lower, p, inner_product);

    if (is_last)
    {
      for (const auto &p : upper)
      {
	output = std::fill_n (output, p.y, p.x / p.y);
      }

      break;
    }
    else
    {
      update (lower, upper, p, [] (auto &&x, auto &&y)
      {
	return inner_product (y, x);
      });
    }
  }

  return output;
}

} // namespace tvf {
<|endoftext|>


<commit_before>/// This file contains the implementation of VNS
#include "header/vns-priv.hpp"

using namespace std;

namespace pcp {
	Solution bestSolution;
	Solution origSolution;

	bool checkValid(Solution* s);

	/// Some constants
	const int NUM_VNS = 2;
	const int SHAKE_START = 1;

	/// Implementation of VNS, see vns.hpp
	Solution vnsRun(Solution& best, Solution& orig, char* units, int unsuccessfulShake,
						 int shakeStart, int shakeIncrement, int maxTime) {

		/// Backup the starting solutions
		bestSolution = new Solution(best);
		origSolution = new Solution(orig);

		if (DEBUG_LEVEL > 1) {
			cout<<"Best solution uses "<<bestSolution.colorsUsed<<" colors"<<endl;
			cout<<"Full solution uses "<<origSolution.colorsUsed<<" colors"<<endl;
		}
		if (DEBUG_LEVEL > 1) {
			cout<<"The supplied solution is valid: "<<(checkValid(&best) ? "true": "false")<<endl;
		}

		/// Define the neighborhoods to use
		VNS_Unit **neighbors = new VNS_Unit*[NUM_VNS];
		changeNode *cN = new changeNode;
		changeColor *cC = new changeColor;
		neighbors[0] = cN;
		neighbors[1] = cC;

		time_t startTime = time(NULL);
		int no_imp_runs = 0;
		int curNeighbor = 0;
		int shakeSteps = shakeStart - shakeIncrement;
		Solution *toImprove = new Solution(&best);
		Solution *curBest = &best;

		/// Run as long as shaking still produces usefull solution
		while (true) {

			/// Run all possible neighborhood
			while (curNeighbor < NUM_VNS) {

				/// Select the new neighborhood
				clock_t start = clock();
				VNS_Unit *neigh = neighbors[curNeighbor];

				if (DEBUG_LEVEL > 1) {
					cout<<"Running: "<< neigh->name() <<endl;
				}

				/// Compute the minimum for this neighborhood
				Solution *improved = neigh->findLocalMin(best, orig);
				if (DEBUG_LEVEL > 1) {
					cout<<neigh->name()<<" took about ";
					cout<<(clock() - start)/(float)CLOCKS_PER_SEC;
					cout<<" seconds to complete"<<endl;
					cout<<"Valid solution: "<<((checkValid(improved)) ? "true" : "false");
					cout<<endl;
				}
				/// Replace the existing solution with the new solution if it is an
				/// improvement
				if (improved->colorsUsed < toImprove->colorsUsed) {
					delete toImprove;
					toImprove = improved;

					if (DEBUG_LEVEL > 1) {
						cout<<"Improvement found with "<<neigh->name()<<endl;
					}

					/// Restart neighborhoods
					curNeighbor = curNeighbor == 0 ? 1 : 0;
				}

				/// Step to next neighborhood, no improvement found
				else {
					if (DEBUG_LEVEL > 1) {
						cout<<"No improvement found"<<endl;
						cout<<"Test next neighborhood"<<endl;
					}
					delete improved;
					curNeighbor++;
				}
				if (DEBUG_LEVEL > 1) {
					cout<<endl;
					cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
					cout<<endl<<endl;
				}
			} // end while neighborhood

			/// Local minimum of neighborhoods is better than current best
			/// solution
			if (toImprove->colorsUsed < best.colorsUsed) {
				if (DEBUG_LEVEL > 1) {
					cout<<"Improvement to global best solution found"<<endl;
				}

				best = toImprove;
				toImprove = new Solution(curBest);
				no_imp_runs = 0;
				shakeSteps = shakeStart - shakeIncrement;
			}
			/// Reset local best solution to global best Solution
			else {
				toImprove = curBest;
				no_imp_runs++;

				/// Stopping condition, quit VNS
				if (no_imp_runs > unsuccessfulShake) {
					if (DEBUG_LEVEL > 0) {
						cout<<"Too many unsuccessful shakes"<<endl;
					}
					break;
				}
			}

			int shakeNeighbor = rand() % NUM_VNS;
			curNeighbor = 0;
			VNS_Unit *shaker = neighbors[shakeNeighbor];
			toImprove = shaker->shuffleSolution(*toImprove, orig, (shakeSteps += shakeIncrement));

			if (DEBUG_LEVEL > 1) {
				cout<<"Shaking Solution using "<<shaker->name()<<" with ";
				cout<<shakeSteps<<" steps"<<endl;
				cout<<"Shake was valid: "<<((checkValid(toImprove)) ? "true" : "false")<<endl;
			}

			/// No time left, abort main loop
			if (startTime + maxTime < time(NULL)) {
				if (DEBUG_LEVEL > 0) {
					cout<<"Time's up"<<endl;
				}
				break;
			}
		}
		if (DEBUG_LEVEL > 0) {
			cout<<endl;
			cout<<"Final best solution uses "<<curBest->colorsUsed<<" colors";
			cout<<endl;
			cout<<"The solution appears to be ";
			cout<<((checkValid(curBest)) ? "valid" : "invalid")<<endl;
		}

		return new Solution(curBest);
	}

	bool checkValid(Solution* s) {
		pair<VertexIter, VertexIter> vIter;
		int parts[s->numParts];
		int colors[s->numParts];
		typedef boost::graph_traits<Graph>::adjacency_iterator AdjIter;
		VertexPart_Map vParts = get(boost::vertex_index1_t(), *s->g);
		bool valid = true;

		for (int i = 0; i < s->numParts; i++) {
			parts[i] = 0;
			colors[i] = 0;
		}

		for (vIter = vertices(*s->g); vIter.first != vIter.second; vIter.first++) {
			parts[vParts[*vIter.first]] = 1;
			colors[s->partition[vParts[*vIter.first]]] = 1;

			pair<AdjIter, AdjIter> aIter;
			for (aIter = adjacent_vertices(*vIter.first, *s->g);
				  aIter.first != aIter.second; aIter.first++) {

				if (s->partition[vParts[*aIter.first]] ==
					 s->partition[vParts[*vIter.first]]) {

					valid = false;
					cerr<<"Solution is invalid"<<endl;
					cerr<<"Adjacent vertices "<<*aIter.first<<" and "<<*vIter.first;
					cerr<<" have same color "<<s->partition[vParts[*vIter.first]];
					cerr<<endl;
				}
			}
		}

		int count = 0;
		for (int i = 0; i < s->numParts; i++) {
			if (colors[i] == 1) {
				count++;
			}
		}
		if (count != s->colorsUsed) {
			valid = false;
			cerr<<"Solution is invalid"<<endl;
			cerr<<"Wrong colorsUsed stored: stored: "<<s->colorsUsed;
			cerr<<", computed: "<<count<<endl;
		}

		for (int i = 0; i < s->numParts; i++) {
			if (parts[i] == 0) {
				valid = false;
				cerr<<"Solution is invalid"<<endl;
				cerr<<"partition "<<i<<" seems to be missing"<<endl;
			}
			if (s->representatives[vParts[i]] != i) {
				valid = false;
				cerr<<"Solution is invalid"<<endl;
				cerr<<"Node "<<i<<" is not representative of partition "<<vParts[i];
				cerr<<endl;
			}
		}

		return valid;
	}
}

<commit_msg>Added comments to checkValid method<commit_after>/// This file contains the implementation of VNS
#include "header/vns-priv.hpp"

using namespace std;

namespace pcp {
	Solution bestSolution;
	Solution origSolution;

	bool checkValid(Solution* s);

	/// Some constants
	const int NUM_VNS = 2;
	const int SHAKE_START = 1;

	/// Implementation of VNS, see vns.hpp
	Solution vnsRun(Solution& best, Solution& orig, char* units, int unsuccessfulShake,
						 int shakeStart, int shakeIncrement, int maxTime) {

		/// Backup the starting solutions
		bestSolution = new Solution(best);
		origSolution = new Solution(orig);

		if (DEBUG_LEVEL > 1) {
			cout<<"Best solution uses "<<bestSolution.colorsUsed<<" colors"<<endl;
			cout<<"Full solution uses "<<origSolution.colorsUsed<<" colors"<<endl;
		}
		if (DEBUG_LEVEL > 1) {
			cout<<"The supplied solution is valid: "<<(checkValid(&best) ? "true": "false")<<endl;
		}

		/// Define the neighborhoods to use
		VNS_Unit **neighbors = new VNS_Unit*[NUM_VNS];
		changeNode *cN = new changeNode;
		changeColor *cC = new changeColor;
		neighbors[0] = cN;
		neighbors[1] = cC;

		time_t startTime = time(NULL);
		int no_imp_runs = 0;
		int curNeighbor = 0;
		int shakeSteps = shakeStart - shakeIncrement;
		Solution *toImprove = new Solution(&best);
		Solution *curBest = &best;

		/// Run as long as shaking still produces usefull solution
		while (true) {

			/// Run all possible neighborhood
			while (curNeighbor < NUM_VNS) {

				/// Select the new neighborhood
				clock_t start = clock();
				VNS_Unit *neigh = neighbors[curNeighbor];

				if (DEBUG_LEVEL > 1) {
					cout<<"Running: "<< neigh->name() <<endl;
				}

				/// Compute the minimum for this neighborhood
				Solution *improved = neigh->findLocalMin(best, orig);
				if (DEBUG_LEVEL > 1) {
					cout<<neigh->name()<<" took about ";
					cout<<(clock() - start)/(float)CLOCKS_PER_SEC;
					cout<<" seconds to complete"<<endl;
					cout<<"Valid solution: "<<((checkValid(improved)) ? "true" : "false");
					cout<<endl;
				}
				/// Replace the existing solution with the new solution if it is an
				/// improvement
				if (improved->colorsUsed < toImprove->colorsUsed) {
					delete toImprove;
					toImprove = improved;

					if (DEBUG_LEVEL > 1) {
						cout<<"Improvement found with "<<neigh->name()<<endl;
					}

					/// Restart neighborhoods
					curNeighbor = curNeighbor == 0 ? 1 : 0;
				}

				/// Step to next neighborhood, no improvement found
				else {
					if (DEBUG_LEVEL > 1) {
						cout<<"No improvement found"<<endl;
						cout<<"Test next neighborhood"<<endl;
					}
					delete improved;
					curNeighbor++;
				}
				if (DEBUG_LEVEL > 1) {
					cout<<endl;
					cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
					cout<<endl<<endl;
				}
			} // end while neighborhood

			/// Local minimum of neighborhoods is better than current best
			/// solution
			if (toImprove->colorsUsed < best.colorsUsed) {
				if (DEBUG_LEVEL > 1) {
					cout<<"Improvement to global best solution found"<<endl;
				}

				best = toImprove;
				toImprove = new Solution(curBest);
				no_imp_runs = 0;
				shakeSteps = shakeStart - shakeIncrement;
			}
			/// Reset local best solution to global best Solution
			else {
				toImprove = curBest;
				no_imp_runs++;

				/// Stopping condition, quit VNS
				if (no_imp_runs > unsuccessfulShake) {
					if (DEBUG_LEVEL > 0) {
						cout<<"Too many unsuccessful shakes"<<endl;
					}
					break;
				}
			}

			int shakeNeighbor = rand() % NUM_VNS;
			curNeighbor = 0;
			VNS_Unit *shaker = neighbors[shakeNeighbor];
			toImprove = shaker->shuffleSolution(*toImprove, orig, (shakeSteps += shakeIncrement));

			if (DEBUG_LEVEL > 1) {
				cout<<"Shaking Solution using "<<shaker->name()<<" with ";
				cout<<shakeSteps<<" steps"<<endl;
				cout<<"Shake was valid: "<<((checkValid(toImprove)) ? "true" : "false")<<endl;
			}

			/// No time left, abort main loop
			if (startTime + maxTime < time(NULL)) {
				if (DEBUG_LEVEL > 0) {
					cout<<"Time's up"<<endl;
				}
				break;
			}
		}
		if (DEBUG_LEVEL > 0) {
			cout<<endl;
			cout<<"Final best solution uses "<<curBest->colorsUsed<<" colors";
			cout<<endl;
			cout<<"The solution appears to be ";
			cout<<((checkValid(curBest)) ? "valid" : "invalid")<<endl;
		}

		return new Solution(curBest);
	}

	/// validate solutions
	bool checkValid(Solution* s) {
		pair<VertexIter, VertexIter> vIter;
		int parts[s->numParts];
		int colors[s->numParts];
		typedef boost::graph_traits<Graph>::adjacency_iterator AdjIter;
		VertexPart_Map vParts = get(boost::vertex_index1_t(), *s->g);
		bool valid = true;

		/// Initialize parts and colors
		for (int i = 0; i < s->numParts; i++) {
			parts[i] = 0;
			colors[i] = 0;
		}

		/// Check all vertices
		for (vIter = vertices(*s->g); vIter.first != vIter.second; vIter.first++) {
			/// Mark partition and color as used
			parts[vParts[*vIter.first]] = 1;
			colors[s->partition[vParts[*vIter.first]]] = 1;

			/// Check color conflicts
			pair<AdjIter, AdjIter> aIter;
			for (aIter = adjacent_vertices(*vIter.first, *s->g);
				  aIter.first != aIter.second; aIter.first++) {

				if (s->partition[vParts[*aIter.first]] ==
					 s->partition[vParts[*vIter.first]]) {

					valid = false;
					cerr<<"Solution is invalid"<<endl;
					cerr<<"Adjacent vertices "<<*aIter.first<<" and "<<*vIter.first;
					cerr<<" have same color "<<s->partition[vParts[*vIter.first]];
					cerr<<endl;
				}
			}
		}

		/// Check colorsUsed
		int count = 0;
		for (int i = 0; i < s->numParts; i++) {
			if (colors[i] == 1) {
				count++;
			}
		}
		if (count != s->colorsUsed) {
			valid = false;
			cerr<<"Solution is invalid"<<endl;
			cerr<<"Wrong colorsUsed stored: stored: "<<s->colorsUsed;
			cerr<<", computed: "<<count<<endl;
		}

		/// Check partitions and representatives
		for (int i = 0; i < s->numParts; i++) {
			if (parts[i] == 0) {
				valid = false;
				cerr<<"Solution is invalid"<<endl;
				cerr<<"partition "<<i<<" seems to be missing"<<endl;
			}
			if (s->representatives[vParts[i]] != i) {
				valid = false;
				cerr<<"Solution is invalid"<<endl;
				cerr<<"Node "<<i<<" is not representative of partition "<<vParts[i];
				cerr<<endl;
			}
		}

		return valid;
	}
}

<|endoftext|>


<commit_before>#ifndef ZIP_HPP
#define ZIP_HPP

#include "iterator_range.hpp"

#include <tuple>
#include <iterator>

namespace iter {
    template <typename ... Rest>
    class zip_iter;

    template <typename ... Containers>
    auto zip(Containers && ... containers) ->
            iterator_range<zip_iter<decltype(std::begin(containers))...>>
    {
        auto begin =
            zip_iter<decltype(containers.begin())...>(std::begin(containers)...);

        auto end =
            zip_iter<decltype(containers.end())...>(std::end(containers)...);

        return iterator_range<decltype(begin)>(begin,end);
    }

    template <typename Iterator>
    class zip_iter<Iterator> {
        private:
            Iterator iter;

        public:
            using elem_type = decltype(*iter);
            zip_iter(const Iterator & i) :
                iter(i){ }

            auto operator*() -> decltype(std::tie(*iter))
            {
                return std::tie(*iter);
            }
            zip_iter & operator++() {
                ++iter;
                return *this;
            }
            bool operator!=(const zip_iter & rhs) const {
                return (this->iter != rhs.iter);
            }
    };
#if 0
    template <typename First, typename Second>
        struct zip_iter<First,Second> {

        private:
            First iter1;
            Second iter2;

        public:
            using Elem1_t = decltype(*iter1);
            using Elem2_t = decltype(*iter2);
            zip_iter(const First & f, const Second & s) :
                iter1(f),iter2(s) { }

            auto operator*() -> decltype(std::tie(*iter1,*iter2))
            {
                return std::tie(*iter1,*iter2);
            }
            zip_iter & operator++() {
                ++iter1;
                ++iter2;
                return *this;
            }
            bool operator!=(const zip_iter & rhs) const {
                return (this->iter1 != rhs.iter1) && (this->iter2 != rhs.iter2);
            }
        };
#endif
    //this specialization commented out
    template <typename First, typename ... Rest>
    class zip_iter<First,Rest...> {
        private:
            First iter;
            zip_iter<Rest...> inner_iter;

        public:
            using elem_type = decltype(*iter);
            using tuple_type =
                decltype(std::tuple_cat(std::tie(*iter),*inner_iter));

            zip_iter(const First & f, const Rest & ... rest) :
                iter(f),
                inner_iter(rest...) {}

            tuple_type operator*()
            {
                return std::tuple_cat(std::tie(*iter),*inner_iter);
            }

            zip_iter & operator++() {
                ++iter;
                ++inner_iter;
                return *this;
            }

            bool operator!=(const zip_iter & rhs) const {
                return (this->iter != rhs.iter) &&
                    (this->inner_iter != rhs.inner_iter);
            }
    };
}

namespace std {
    template <typename ... Containers>
        struct iterator_traits<iter::zip_iter<Containers...>> {
            using difference_type = ptrdiff_t;
            using iterator_category = input_iterator_tag;
        };
}
#endif //ZIP_HPP
<commit_msg>changed std::tie to std::forward_as_tuple<commit_after>#ifndef ZIP_HPP
#define ZIP_HPP

#include "iterator_range.hpp"

#include <tuple>
#include <iterator>

namespace iter {
    template <typename ... Rest>
    class zip_iter;

    template <typename ... Containers>
    auto zip(Containers && ... containers) ->
            iterator_range<zip_iter<decltype(std::begin(containers))...>>
    {
        auto begin =
            zip_iter<decltype(containers.begin())...>(std::begin(containers)...);

        auto end =
            zip_iter<decltype(containers.end())...>(std::end(containers)...);

        return iterator_range<decltype(begin)>(begin,end);
    }

    template <typename Iterator>
    class zip_iter<Iterator> {
        private:
            Iterator iter;

        public:
            using elem_type = decltype(*iter);
            zip_iter(const Iterator & i) :
                iter(i){ }

            auto operator*() -> decltype(std::forward_as_tuple(*iter))
            {
                return std::forward_as_tuple(*iter);
            }
            zip_iter & operator++() {
                ++iter;
                return *this;
            }
            bool operator!=(const zip_iter & rhs) const {
                return (this->iter != rhs.iter);
            }
    };
#if 0
    template <typename First, typename Second>
        struct zip_iter<First,Second> {

        private:
            First iter1;
            Second iter2;

        public:
            using Elem1_t = decltype(*iter1);
            using Elem2_t = decltype(*iter2);
            zip_iter(const First & f, const Second & s) :
                iter1(f),iter2(s) { }

            auto operator*() -> decltype(std::forward_as_tuple(*iter1,*iter2))
            {
                return std::forward_as_tuple(*iter1,*iter2);
            }
            zip_iter & operator++() {
                ++iter1;
                ++iter2;
                return *this;
            }
            bool operator!=(const zip_iter & rhs) const {
                return (this->iter1 != rhs.iter1) && (this->iter2 != rhs.iter2);
            }
        };
#endif
    //this specialization commented out
    template <typename First, typename ... Rest>
    class zip_iter<First,Rest...> {
        private:
            First iter;
            zip_iter<Rest...> inner_iter;

        public:
            using elem_type = decltype(*iter);
            using tuple_type =
                decltype(std::tuple_cat(std::forward_as_tuple(*iter),*inner_iter));

            zip_iter(const First & f, const Rest & ... rest) :
                iter(f),
                inner_iter(rest...) {}

            tuple_type operator*()
            {
                return std::tuple_cat(std::forward_as_tuple(*iter),*inner_iter);
            }

            zip_iter & operator++() {
                ++iter;
                ++inner_iter;
                return *this;
            }

            bool operator!=(const zip_iter & rhs) const {
                return (this->iter != rhs.iter) &&
                    (this->inner_iter != rhs.inner_iter);
            }
    };
}

namespace std {
    template <typename ... Containers>
        struct iterator_traits<iter::zip_iter<Containers...>> {
            using difference_type = ptrdiff_t;
            using iterator_category = input_iterator_tag;
        };
}
#endif //ZIP_HPP
<|endoftext|>


<commit_before>#include "voip.h"
#include "Central.h"

using namespace ns3;
#define MAXONVOIP 0.1
#define MINONVOIP 0.2
#define MAXOFFVOIP 0.8
#define MINOFFVOIP 0.9

voip::voip (Central * centralita, uint64_t tamPkt, Time media, Time duracion, DataRate tasaCodec[2], Address IP, Ptr<Node> node) : OnOffHelper("ns3::UdpSocketFactory", IP)
{

	m_centralita = centralita;
	m_ocupado = false;
	m_tamPaquete = tamPkt;
	tiempo_entre_llamadas.SetAttribute("Mean",DoubleValue(media.GetSeconds()) );
	duracion_de_llamada.SetAttribute("Mean", DoubleValue (duracion.GetSeconds()));
    uint32_t minTasa = tasaCodec[0].GetBitRate();
    uint32_t maxTasa = tasaCodec[1].GetBitRate();
    m_tasa = tasa_llamadas.GetValue(minTasa,maxTasa);
    m_IP = IP;
    m_node = node;
    m_numeroNodo = m_centralita->registrar (m_IP);
}

void
voip::setDestino (Address destino){

	m_destino = destino;
}

void
voip::setTamPaquete (uint64_t tamPkt){

	m_tamPaquete = tamPkt;

}

bool
voip::getOcupado(){
return m_ocupado;
}

void voip::CancelaLlamada (){

Simulator::Cancel(m_proximallamada);
}

void voip::ProgramaLlamada (){

	m_proximallamada=Simulator::Schedule (Time (tiempo_entre_llamadas.GetValue()) , this, Llama ); //m_tiempo no es tipo Time, falla

}

void
voip::Llama (){

	//Me pongo en contacto con la centralita
	m_ocupado=true;
	m_llamadaactual = m_proximallamada;
	m_duracion = Time(duracion_de_llamada.GetValue());

		Address direccion_envio = m_centralita->llamar ( m_numeroNodo, m_duracion);

	//Configuro OnOff?

		m_AppOnOff = OnOffHelper("ns3::UdpSocketFactory", direccion_envio);

		m_AppOnOff.SetConstantRate (DataRate( m_tasa) );
		m_AppOnOff.SetAttribute("PacketSize",UintegerValue( m_tamPaquete) );

	  varon=CreateObject<UniformRandomVariable>();
	  varon->SetAttribute("Max", DoubleValue(MAXONVOIP));
	  varon->SetAttribute("Min", DoubleValue(MINONVOIP));

	  varoff=CreateObject<UniformRandomVariable>();
	  varoff->SetAttribute("Max", DoubleValue(MAXOFFVOIP));
	  varoff->SetAttribute("Min", DoubleValue(MINOFFVOIP));
	  //Configuramos la aplicación OnOff

	  m_AppOnOff.SetAttribute("OnTime", PointerValue(varon));
	  m_AppOnOff.SetAttribute("OffTime", PointerValue(varoff));

	  m_appc = m_AppOnOff.Install(m_node); //Pasarle por parametro al puntero al nodo.
	  m_appc.Start(Simulator::Now());
	  Simulator::Schedule (Simulator::Now()+m_duracion,this, Cuelga);

}

void
voip::Cuelga(){

	//llamo al OnOffStopApplication
	m_appc.Stop(Simulator::Now());
	m_ocupado=0;
	//Llamo a programallamada
	ProgramaLlamada();

}

void voip::Descuelga(Address destino, Time duracion){

	CancelaLlamada();

	m_AppOnOff = OnOffHelper("ns3::UdpSocketFactory", destino);

			m_AppOnOff.SetConstantRate (DataRate( m_tasa) );

		  varon=CreateObject<UniformRandomVariable>();
		  varon->SetAttribute("Max", DoubleValue(MAXONVOIP));
		  varon->SetAttribute("Min", DoubleValue(MINONVOIP));

		  varoff=CreateObject<UniformRandomVariable>();
		  varoff->SetAttribute("Max", DoubleValue(MAXOFFVOIP));
		  varoff->SetAttribute("Min", DoubleValue(MINOFFVOIP));
		  //Configuramos la aplicación OnOff

		  m_AppOnOff.SetAttribute("OnTime", PointerValue(varon));
		  m_AppOnOff.SetAttribute("OffTime", PointerValue(varoff));

		  m_appc = m_AppOnOff.Install(m_node); //Pasarle por parametro al puntero al nodo.
		  m_appc.Start(Simulator::Now());
		  Simulator::Schedule (Simulator::Now()+m_duracion,this, Cuelga);

}
<commit_msg>Deshecho<commit_after>#include "voip.h"
#include "Central.h"

using namespace ns3;
#define MAXONVOIP 0.1
#define MINONVOIP 0.2
#define MAXOFFVOIP 0.8
#define MINOFFVOIP 0.9

voip::voip (Central * centralita, uint64_t tamPkt, Time media, Time duracion, DataRate tasaCodec[2], Address IP, Ptr<Node> node) : Application()
{

	m_centralita = centralita;
	m_ocupado = false;
	m_tamPaquete = tamPkt;
	tiempo_entre_llamadas.SetAttribute("Mean",DoubleValue(media.GetSeconds()) );
	duracion_de_llamada.SetAttribute("Mean", DoubleValue (duracion.GetSeconds()));
    uint32_t minTasa = tasaCodec[0].GetBitRate();
    uint32_t maxTasa = tasaCodec[1].GetBitRate();
    m_tasa = tasa_llamadas.GetValue(minTasa,maxTasa);
    m_IP = IP;
    m_node = node;
    m_numeroNodo = m_centralita->registrar (m_IP);
}

void
voip::setDestino (Address destino){

	m_destino = destino;
}

void
voip::setTamPaquete (uint64_t tamPkt){

	m_tamPaquete = tamPkt;

}

bool
voip::getOcupado(){
return m_ocupado;
}

void voip::CancelaLlamada (){

Simulator::Cancel(m_proximallamada);
}

void voip::ProgramaLlamada (){

	m_proximallamada=Simulator::Schedule (Time (tiempo_entre_llamadas.GetValue()) , this, Llama ); //m_tiempo no es tipo Time, falla

}

void
voip::Llama (){

	//Me pongo en contacto con la centralita
	m_ocupado=true;
	m_llamadaactual = m_proximallamada;
	m_duracion = Time(duracion_de_llamada.GetValue());

		Address direccion_envio = m_centralita->llamar ( m_numeroNodo, m_duracion);

	//Configuro OnOff?

		m_AppOnOff = OnOffHelper("ns3::UdpSocketFactory", direccion_envio);

		m_AppOnOff.SetConstantRate (DataRate( m_tasa) );
		m_AppOnOff.SetAttribute("PacketSize",UintegerValue( m_tamPaquete) );

	  varon=CreateObject<UniformRandomVariable>();
	  varon->SetAttribute("Max", DoubleValue(MAXONVOIP));
	  varon->SetAttribute("Min", DoubleValue(MINONVOIP));

	  varoff=CreateObject<UniformRandomVariable>();
	  varoff->SetAttribute("Max", DoubleValue(MAXOFFVOIP));
	  varoff->SetAttribute("Min", DoubleValue(MINOFFVOIP));
	  //Configuramos la aplicación OnOff

	  m_AppOnOff.SetAttribute("OnTime", PointerValue(varon));
	  m_AppOnOff.SetAttribute("OffTime", PointerValue(varoff));

	  m_appc = m_AppOnOff.Install(m_node); //Pasarle por parametro al puntero al nodo.
	  m_appc.Start(Simulator::Now());
	  Simulator::Schedule (Simulator::Now()+m_duracion,this, Cuelga);

}

void
voip::Cuelga(){

	//llamo al OnOffStopApplication
	m_appc.Stop(Simulator::Now());
	m_ocupado=0;
	//Llamo a programallamada
	ProgramaLlamada();

}

void voip::Descuelga(Address destino, Time duracion){

	CancelaLlamada();

	m_AppOnOff = OnOffHelper("ns3::UdpSocketFactory", destino);

			m_AppOnOff.SetConstantRate (DataRate( m_tasa) );

		  varon=CreateObject<UniformRandomVariable>();
		  varon->SetAttribute("Max", DoubleValue(MAXONVOIP));
		  varon->SetAttribute("Min", DoubleValue(MINONVOIP));

		  varoff=CreateObject<UniformRandomVariable>();
		  varoff->SetAttribute("Max", DoubleValue(MAXOFFVOIP));
		  varoff->SetAttribute("Min", DoubleValue(MINOFFVOIP));
		  //Configuramos la aplicación OnOff

		  m_AppOnOff.SetAttribute("OnTime", PointerValue(varon));
		  m_AppOnOff.SetAttribute("OffTime", PointerValue(varoff));

		  m_appc = m_AppOnOff.Install(m_node); //Pasarle por parametro al puntero al nodo.
		  m_appc.Start(Simulator::Now());
		  Simulator::Schedule (Simulator::Now()+m_duracion,this, Cuelga);

}
<|endoftext|>


<commit_before>/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
/*
    MaSzyna EU07 locomotive simulator
    Copyright (C) 2001-2004  Marcin Wozniak, Maciej Czapkiewicz and others

*/
/*
Authors:
MarcinW, McZapkie, Shaxbee, ABu, nbmx, youBy, Ra, winger, mamut, Q424,
Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others
*/

#include "stdafx.h"
#include <png.h>
#include <thread>
#include <direct.h>

#include "Globals.h"
#include "Logs.h"
#include "keyboardinput.h"
#include "gamepadinput.h"
#include "Console.h"
#include "PyInt.h"
#include "World.h"
#include "Mover.h"
#include "usefull.h"
#include "timer.h"
#include "resource.h"
#include "uilayer.h"

#pragma comment (lib, "glu32.lib")
#pragma comment (lib, "dsound.lib")
#pragma comment (lib, "winmm.lib")
#pragma comment (lib, "setupapi.lib")
#pragma comment (lib, "dbghelp.lib")

TWorld World;

namespace input {

keyboard_input Keyboard;
gamepad_input Gamepad;

}

void screenshot_save_thread( char *img )
{
	png_image png;
	memset(&png, 0, sizeof(png_image));
	png.version = PNG_IMAGE_VERSION;
	png.width = Global::ScreenWidth;
	png.height = Global::ScreenHeight;
	png.format = PNG_FORMAT_RGB;

	char datetime[64];
	time_t timer;
	struct tm* tm_info;
	time(&timer);
	tm_info = localtime(&timer);
	strftime(datetime, 64, "%Y-%m-%d_%H-%M-%S", tm_info);

	uint64_t perf;
	QueryPerformanceCounter((LARGE_INTEGER*)&perf);

	std::string filename = "screenshots/" + std::string(datetime) +
	                       "_" + std::to_string(perf) + ".png";

	if (png_image_write_to_file(&png, filename.c_str(), 0, img, -Global::ScreenWidth * 3, nullptr) == 1)
		WriteLog("saved " + filename + ".");
	else
		WriteLog("failed to save screenshot.");

	delete[] img;
}

void make_screenshot()
{
	char *img = new char[Global::ScreenWidth * Global::ScreenHeight * 3];
	glReadPixels(0, 0, Global::ScreenWidth, Global::ScreenHeight, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img);

	std::thread t(screenshot_save_thread, img);
	t.detach();
}

void window_resize_callback(GLFWwindow *window, int w, int h)
{
    // NOTE: we have two variables which basically do the same thing as we don't have dynamic fullscreen toggle
    // TBD, TODO: merge them?
	Global::ScreenWidth = Global::iWindowWidth = w;
	Global::ScreenHeight = Global::iWindowHeight = h;
    Global::fDistanceFactor = std::max( 0.5f, h / 768.0f ); // not sure if this is really something we want to use
	glViewport(0, 0, w, h);
}

void cursor_pos_callback(GLFWwindow *window, double x, double y)
{
    input::Keyboard.mouse( x, y );
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
	World.OnMouseMove(x * 0.005, y * 0.01);
#endif
	glfwSetCursorPos(window, 0.0, 0.0);
}

void key_callback( GLFWwindow *window, int key, int scancode, int action, int mods )
{
    input::Keyboard.key( key, action );

    Global::shiftState = ( mods & GLFW_MOD_SHIFT ) ? true : false;
    Global::ctrlState = ( mods & GLFW_MOD_CONTROL ) ? true : false;

    if( ( key == GLFW_KEY_LEFT_SHIFT )
     || ( key == GLFW_KEY_LEFT_CONTROL )
     || ( key == GLFW_KEY_LEFT_ALT )
     || ( key == GLFW_KEY_RIGHT_SHIFT )
     || ( key == GLFW_KEY_RIGHT_CONTROL )
     || ( key == GLFW_KEY_RIGHT_ALT ) ) {
        // don't bother passing these
        return;
    }

    if( action == GLFW_PRESS || action == GLFW_REPEAT )
    {
        World.OnKeyDown( key );

        switch( key )
        {

            case GLFW_KEY_F11: {
                make_screenshot();
                break;
            }

            default: { break; }
        }
    }
}

void focus_callback( GLFWwindow *window, int focus )
{
    if( Global::bInactivePause ) // jeśli ma być pauzowanie okna w tle
        if( focus )
            Global::iPause &= ~4; // odpauzowanie, gdy jest na pierwszym planie
        else
            Global::iPause |= 4; // włączenie pauzy, gdy nieaktywy
}

void scroll_callback( GLFWwindow* window, double xoffset, double yoffset ) {

    if( Global::ctrlState ) {
        // ctrl + scroll wheel adjusts fov in debug mode
        Global::FieldOfView = clamp( static_cast<float>(Global::FieldOfView - yoffset * 20.0 / Global::fFpsAverage), 15.0f, 75.0f );
    }
}

#ifdef _WINDOWS
extern "C"
{
    GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
}

LONG CALLBACK unhandled_handler(::EXCEPTION_POINTERS* e);
LRESULT APIENTRY WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
extern HWND Hwnd;
extern WNDPROC BaseWindowProc;
#endif

int main(int argc, char *argv[])
{
#ifdef _WINDOWS
	::SetUnhandledExceptionFilter(unhandled_handler);
#endif

	if (!glfwInit())
		return -1;

#ifdef _WINDOWS
    DeleteFile( "log.txt" );
    DeleteFile( "errors.txt" );
    mkdir("logs");
#endif
    Global::LoadIniFile("eu07.ini");
    Global::InitKeys();

    // hunter-271211: ukrywanie konsoli
    if( Global::iWriteLogEnabled & 2 )
	{
        AllocConsole();
        SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), FOREGROUND_GREEN );
    }

	for (int i = 1; i < argc; i++)
	{
		std::string token(argv[i]);

		if (token == "-modifytga")
			Global::iModifyTGA = -1;
		else if (token == "-e3d")
		{
			if (Global::iConvertModels > 0)
				Global::iConvertModels = -Global::iConvertModels;
			else
				Global::iConvertModels = -7; // z optymalizacją, bananami i prawidłowym Opacity
		}
		else if (i + 1 < argc && token == "-s")
			Global::SceneryFile = std::string(argv[++i]);
		else if (i + 1 < argc && token == "-v")
		{
			std::string v(argv[++i]);
			std::transform(v.begin(), v.end(), v.begin(), ::tolower);
			Global::asHumanCtrlVehicle = v;
		}
		else
		{
			std::cout << "usage: " << std::string(argv[0]) << " [-s sceneryfilepath] "
				      << "[-v vehiclename] [-modifytga] [-e3d]" << std::endl;
			return -1;
		}
	}

    // match requested video mode to current to allow for
    // fullwindow creation when resolution is the same
    GLFWmonitor *monitor = glfwGetPrimaryMonitor();
    const GLFWvidmode *vmode = glfwGetVideoMode(monitor);

    glfwWindowHint(GLFW_RED_BITS, vmode->redBits);
    glfwWindowHint(GLFW_GREEN_BITS, vmode->greenBits);
    glfwWindowHint(GLFW_BLUE_BITS, vmode->blueBits);
    glfwWindowHint(GLFW_REFRESH_RATE, vmode->refreshRate);

    glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
    if( Global::iMultisampling > 0 ) {
        glfwWindowHint( GLFW_SAMPLES, 1 << Global::iMultisampling );
    }

    if (Global::bFullScreen)
	{
        // match screen dimensions with selected monitor, for 'borderless window' in fullscreen mode
        Global::iWindowWidth = vmode->width;
        Global::iWindowHeight = vmode->height;
    }

    GLFWwindow *window =
        glfwCreateWindow( Global::iWindowWidth, Global::iWindowHeight,
			Global::AppName.c_str(), Global::bFullScreen ? monitor : nullptr, nullptr );

    if (!window)
	{
        std::cout << "failed to create window" << std::endl;
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(Global::VSync ? 1 : 0); //vsync
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); //capture cursor
    glfwSetCursorPos(window, 0.0, 0.0);
    glfwSetFramebufferSizeCallback(window, window_resize_callback);
    glfwSetCursorPosCallback(window, cursor_pos_callback);
    glfwSetKeyCallback(window, key_callback);
    glfwSetScrollCallback( window, scroll_callback );
    glfwSetWindowFocusCallback(window, focus_callback);
    {
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        window_resize_callback(window, width, height);
    }

    if (glewInit() != GLEW_OK)
	{
        std::cout << "failed to init GLEW" << std::endl;
        return -1;
    }

#ifdef _WINDOWS
    // setup wrapper for base glfw window proc, to handle copydata messages
    Hwnd = glfwGetWin32Window( window );
    BaseWindowProc = (WNDPROC)::SetWindowLongPtr( Hwnd, GWLP_WNDPROC, (LONG_PTR)WndProc );
    // switch off the topmost flag
    ::SetWindowPos( Hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );

    const HANDLE icon = ::LoadImage(
        ::GetModuleHandle( 0 ),
        MAKEINTRESOURCE( IDI_ICON1 ),
        IMAGE_ICON,
        ::GetSystemMetrics( SM_CXSMICON ),
        ::GetSystemMetrics( SM_CYSMICON ),
        0 );
    if( icon )
        ::SendMessage( Hwnd, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>( icon ) );
#endif

    if( ( false == GfxRenderer.Init( window ) )
     || ( false == UILayer.init( window ) ) ) {

        return -1;
    }
    input::Keyboard.init();
    input::Gamepad.init();

    Global::pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów
	try
	{
		if (!World.Init(window))
		{
			std::cout << "failed to init TWorld" << std::endl;
			return -1;
		}
	}
	catch (std::runtime_error e)
	{
		WriteLog(e.what());
		return -1;
	}

    Console *pConsole = new Console(); // Ra: nie wiem, czy ma to sens, ale jakoś zainicjowac trzeba
/*
    if( !joyGetNumDevs() )
        WriteLog( "No joystick" );
*/
    if( Global::iModifyTGA < 0 ) { // tylko modyfikacja TGA, bez uruchamiania symulacji
        Global::iMaxTextureSize = 64; //żeby nie zamulać pamięci
        World.ModifyTGA(); // rekurencyjne przeglądanie katalogów
    }
    else {
        if( Global::iConvertModels < 0 ) {
            Global::iConvertModels = -Global::iConvertModels;
            World.CreateE3D( "models\\" ); // rekurencyjne przeglądanie katalogów
            World.CreateE3D( "dynamic\\", true );
        } // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć

        Console::On(); // włączenie konsoli
        while (!glfwWindowShouldClose(window)
            && World.Update()
            && GfxRenderer.Render())
        {
            glfwPollEvents();
            input::Gamepad.poll();
        }
        Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej)
    }

	TPythonInterpreter::killInstance();
	delete pConsole;

	glfwDestroyWindow(window);
	glfwTerminate();

	return 0;
}
<commit_msg>catch exceptions in gfxrenderer init and other inits<commit_after>/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
/*
    MaSzyna EU07 locomotive simulator
    Copyright (C) 2001-2004  Marcin Wozniak, Maciej Czapkiewicz and others

*/
/*
Authors:
MarcinW, McZapkie, Shaxbee, ABu, nbmx, youBy, Ra, winger, mamut, Q424,
Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others
*/

#include "stdafx.h"
#include <png.h>
#include <thread>
#include <direct.h>

#include "Globals.h"
#include "Logs.h"
#include "keyboardinput.h"
#include "gamepadinput.h"
#include "Console.h"
#include "PyInt.h"
#include "World.h"
#include "Mover.h"
#include "usefull.h"
#include "timer.h"
#include "resource.h"
#include "uilayer.h"

#pragma comment (lib, "glu32.lib")
#pragma comment (lib, "dsound.lib")
#pragma comment (lib, "winmm.lib")
#pragma comment (lib, "setupapi.lib")
#pragma comment (lib, "dbghelp.lib")

TWorld World;

namespace input {

keyboard_input Keyboard;
gamepad_input Gamepad;

}

void screenshot_save_thread( char *img )
{
	png_image png;
	memset(&png, 0, sizeof(png_image));
	png.version = PNG_IMAGE_VERSION;
	png.width = Global::ScreenWidth;
	png.height = Global::ScreenHeight;
	png.format = PNG_FORMAT_RGB;

	char datetime[64];
	time_t timer;
	struct tm* tm_info;
	time(&timer);
	tm_info = localtime(&timer);
	strftime(datetime, 64, "%Y-%m-%d_%H-%M-%S", tm_info);

	uint64_t perf;
	QueryPerformanceCounter((LARGE_INTEGER*)&perf);

	std::string filename = "screenshots/" + std::string(datetime) +
	                       "_" + std::to_string(perf) + ".png";

	if (png_image_write_to_file(&png, filename.c_str(), 0, img, -Global::ScreenWidth * 3, nullptr) == 1)
		WriteLog("saved " + filename + ".");
	else
		WriteLog("failed to save screenshot.");

	delete[] img;
}

void make_screenshot()
{
	char *img = new char[Global::ScreenWidth * Global::ScreenHeight * 3];
	glReadPixels(0, 0, Global::ScreenWidth, Global::ScreenHeight, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img);

	std::thread t(screenshot_save_thread, img);
	t.detach();
}

void window_resize_callback(GLFWwindow *window, int w, int h)
{
    // NOTE: we have two variables which basically do the same thing as we don't have dynamic fullscreen toggle
    // TBD, TODO: merge them?
	Global::ScreenWidth = Global::iWindowWidth = w;
	Global::ScreenHeight = Global::iWindowHeight = h;
    Global::fDistanceFactor = std::max( 0.5f, h / 768.0f ); // not sure if this is really something we want to use
	glViewport(0, 0, w, h);
}

void cursor_pos_callback(GLFWwindow *window, double x, double y)
{
    input::Keyboard.mouse( x, y );
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
	World.OnMouseMove(x * 0.005, y * 0.01);
#endif
	glfwSetCursorPos(window, 0.0, 0.0);
}

void key_callback( GLFWwindow *window, int key, int scancode, int action, int mods )
{
    input::Keyboard.key( key, action );

    Global::shiftState = ( mods & GLFW_MOD_SHIFT ) ? true : false;
    Global::ctrlState = ( mods & GLFW_MOD_CONTROL ) ? true : false;

    if( ( key == GLFW_KEY_LEFT_SHIFT )
     || ( key == GLFW_KEY_LEFT_CONTROL )
     || ( key == GLFW_KEY_LEFT_ALT )
     || ( key == GLFW_KEY_RIGHT_SHIFT )
     || ( key == GLFW_KEY_RIGHT_CONTROL )
     || ( key == GLFW_KEY_RIGHT_ALT ) ) {
        // don't bother passing these
        return;
    }

    if( action == GLFW_PRESS || action == GLFW_REPEAT )
    {
        World.OnKeyDown( key );

        switch( key )
        {

            case GLFW_KEY_F11: {
                make_screenshot();
                break;
            }

            default: { break; }
        }
    }
}

void focus_callback( GLFWwindow *window, int focus )
{
    if( Global::bInactivePause ) // jeśli ma być pauzowanie okna w tle
        if( focus )
            Global::iPause &= ~4; // odpauzowanie, gdy jest na pierwszym planie
        else
            Global::iPause |= 4; // włączenie pauzy, gdy nieaktywy
}

void scroll_callback( GLFWwindow* window, double xoffset, double yoffset ) {

    if( Global::ctrlState ) {
        // ctrl + scroll wheel adjusts fov in debug mode
        Global::FieldOfView = clamp( static_cast<float>(Global::FieldOfView - yoffset * 20.0 / Global::fFpsAverage), 15.0f, 75.0f );
    }
}

#ifdef _WINDOWS
extern "C"
{
    GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
}

LONG CALLBACK unhandled_handler(::EXCEPTION_POINTERS* e);
LRESULT APIENTRY WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
extern HWND Hwnd;
extern WNDPROC BaseWindowProc;
#endif

int main(int argc, char *argv[])
{
#ifdef _WINDOWS
	::SetUnhandledExceptionFilter(unhandled_handler);
#endif

	if (!glfwInit())
		return -1;

#ifdef _WINDOWS
    DeleteFile( "log.txt" );
    DeleteFile( "errors.txt" );
    mkdir("logs");
#endif
    Global::LoadIniFile("eu07.ini");
    Global::InitKeys();

    // hunter-271211: ukrywanie konsoli
    if( Global::iWriteLogEnabled & 2 )
	{
        AllocConsole();
        SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), FOREGROUND_GREEN );
    }

	for (int i = 1; i < argc; i++)
	{
		std::string token(argv[i]);

		if (token == "-modifytga")
			Global::iModifyTGA = -1;
		else if (token == "-e3d")
		{
			if (Global::iConvertModels > 0)
				Global::iConvertModels = -Global::iConvertModels;
			else
				Global::iConvertModels = -7; // z optymalizacją, bananami i prawidłowym Opacity
		}
		else if (i + 1 < argc && token == "-s")
			Global::SceneryFile = std::string(argv[++i]);
		else if (i + 1 < argc && token == "-v")
		{
			std::string v(argv[++i]);
			std::transform(v.begin(), v.end(), v.begin(), ::tolower);
			Global::asHumanCtrlVehicle = v;
		}
		else
		{
			std::cout << "usage: " << std::string(argv[0]) << " [-s sceneryfilepath] "
				      << "[-v vehiclename] [-modifytga] [-e3d]" << std::endl;
			return -1;
		}
	}

    // match requested video mode to current to allow for
    // fullwindow creation when resolution is the same
    GLFWmonitor *monitor = glfwGetPrimaryMonitor();
    const GLFWvidmode *vmode = glfwGetVideoMode(monitor);

    glfwWindowHint(GLFW_RED_BITS, vmode->redBits);
    glfwWindowHint(GLFW_GREEN_BITS, vmode->greenBits);
    glfwWindowHint(GLFW_BLUE_BITS, vmode->blueBits);
    glfwWindowHint(GLFW_REFRESH_RATE, vmode->refreshRate);

    glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
    if( Global::iMultisampling > 0 ) {
        glfwWindowHint( GLFW_SAMPLES, 1 << Global::iMultisampling );
    }

    if (Global::bFullScreen)
	{
        // match screen dimensions with selected monitor, for 'borderless window' in fullscreen mode
        Global::iWindowWidth = vmode->width;
        Global::iWindowHeight = vmode->height;
    }

    GLFWwindow *window =
        glfwCreateWindow( Global::iWindowWidth, Global::iWindowHeight,
			Global::AppName.c_str(), Global::bFullScreen ? monitor : nullptr, nullptr );

    if (!window)
	{
        std::cout << "failed to create window" << std::endl;
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(Global::VSync ? 1 : 0); //vsync
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); //capture cursor
    glfwSetCursorPos(window, 0.0, 0.0);
    glfwSetFramebufferSizeCallback(window, window_resize_callback);
    glfwSetCursorPosCallback(window, cursor_pos_callback);
    glfwSetKeyCallback(window, key_callback);
    glfwSetScrollCallback( window, scroll_callback );
    glfwSetWindowFocusCallback(window, focus_callback);
    {
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        window_resize_callback(window, width, height);
    }

    if (glewInit() != GLEW_OK)
	{
        std::cout << "failed to init GLEW" << std::endl;
        return -1;
    }

#ifdef _WINDOWS
    // setup wrapper for base glfw window proc, to handle copydata messages
    Hwnd = glfwGetWin32Window( window );
    BaseWindowProc = (WNDPROC)::SetWindowLongPtr( Hwnd, GWLP_WNDPROC, (LONG_PTR)WndProc );
    // switch off the topmost flag
    ::SetWindowPos( Hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );

    const HANDLE icon = ::LoadImage(
        ::GetModuleHandle( 0 ),
        MAKEINTRESOURCE( IDI_ICON1 ),
        IMAGE_ICON,
        ::GetSystemMetrics( SM_CXSMICON ),
        ::GetSystemMetrics( SM_CYSMICON ),
        0 );
    if( icon )
        ::SendMessage( Hwnd, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>( icon ) );
#endif

    Global::pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów
	try
	{
		if ((false == GfxRenderer.Init(window))
			|| (false == UILayer.init(window)))
			return -1;
		input::Keyboard.init();
		input::Gamepad.init();

		if (!World.Init(window))
		{
			std::cout << "failed to init TWorld" << std::endl;
			return -1;
		}
	}
	catch (std::runtime_error e)
	{
		WriteLog(e.what());
		return -1;
	}

    Console *pConsole = new Console(); // Ra: nie wiem, czy ma to sens, ale jakoś zainicjowac trzeba
/*
    if( !joyGetNumDevs() )
        WriteLog( "No joystick" );
*/
    if( Global::iModifyTGA < 0 ) { // tylko modyfikacja TGA, bez uruchamiania symulacji
        Global::iMaxTextureSize = 64; //żeby nie zamulać pamięci
        World.ModifyTGA(); // rekurencyjne przeglądanie katalogów
    }
    else {
        if( Global::iConvertModels < 0 ) {
            Global::iConvertModels = -Global::iConvertModels;
            World.CreateE3D( "models\\" ); // rekurencyjne przeglądanie katalogów
            World.CreateE3D( "dynamic\\", true );
        } // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć

        Console::On(); // włączenie konsoli
        while (!glfwWindowShouldClose(window)
            && World.Update()
            && GfxRenderer.Render())
        {
            glfwPollEvents();
            input::Gamepad.poll();
        }
        Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej)
    }

	TPythonInterpreter::killInstance();
	delete pConsole;

	glfwDestroyWindow(window);
	glfwTerminate();

	return 0;
}
<|endoftext|>


<commit_before>/*
Copyright 2014-2015 Adam Grandquist

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.
 */
/**
 * @author Adam Grandquist
 * @copyright Apache
 */

#include "ReQL.hpp"

namespace ReQL {

Result::Result() : type(REQL_R_JSON) {}

Result::Result(const Result &other) {
  value.copy(other.value, type);
}

Result::Result(Result &&other) {
  value.move(std::move(other.value), type);
}

Result::~Result() {
  value.release(type);
}

Result &
Result::operator=(const Result &other) {
  if (this != &other) {
    value.copy(other.value, type);
  }
  return *this;
}

Result &
Result::operator=(Result &&other) {
  if (this != &other) {
    value.move(std::move(other.value), type);
  }
  return *this;
}

Result::JSON_Value::JSON_Value() {
  std::memset(this, 0, sizeof(Result::JSON_Value));
}

void
Result::JSON_Value::copy(const Result::JSON_Value &other, ReQL_Datum_t type) {
  switch (type) {
    case REQL_R_ARRAY: {
      array = other.array;
      break;
    }
    case REQL_R_BOOL: {
      boolean = other.boolean;
      break;
    }
    case REQL_R_NUM: {
      num = other.num;
      break;
    }
    case REQL_R_OBJECT: {
      object = other.object;
      break;
    }
    case REQL_R_STR: {
      string = other.string;
      break;
    }
    case REQL_R_NULL:
    case REQL_R_JSON:
    case REQL_R_REQL: break;
  }
}

void
Result::JSON_Value::move(Result::JSON_Value &&other, ReQL_Datum_t type) {
  switch (type) {
    case REQL_R_ARRAY: {
      array = std::move(other.array);
      break;
    }
    case REQL_R_BOOL: {
      boolean = std::move(other.boolean);
      break;
    }
    case REQL_R_NUM: {
      num = std::move(other.num);
      break;
    }
    case REQL_R_OBJECT: {
      object = std::move(other.object);
      break;
    }
    case REQL_R_STR: {
      string = std::move(other.string);
      break;
    }
    case REQL_R_NULL:
    case REQL_R_JSON:
    case REQL_R_REQL: break;
  }
}

void
Result::JSON_Value::release(ReQL_Datum_t type) {
  switch (type) {
    case REQL_R_ARRAY: {
      array.~vector();
      break;
    }
    case REQL_R_OBJECT: {
      object.~map();
      break;
    }
    case REQL_R_STR: {
      string.~basic_string();
      break;
    }
    case REQL_R_BOOL:
    case REQL_R_JSON:
    case REQL_R_NULL:
    case REQL_R_NUM:
    case REQL_R_REQL: break;
  }
}

Result::JSON_Value::~JSON_Value() {
  std::memset(this, 0, sizeof(Result::JSON_Value));
}

void
Parser::parse(ReQL_Obj_t *val) {
  switch (reql_datum_type(val)) {
    case REQL_R_ARRAY: {
      startArray();

      ReQL_Iter_t it = reql_new_iter(val);
      ReQL_Obj_t *elem = NULL;

      while ((elem = reql_iter_next(&it)) != NULL) {
        parse(elem);
      }

      endArray();
      break;
    }
    case REQL_R_BOOL: {
      addElement(static_cast<bool>(reql_to_bool(val)));
      break;
    }
    case REQL_R_JSON:
    case REQL_R_REQL: break;
    case REQL_R_NULL: {
      addElement();
      break;
    }
    case REQL_R_NUM: {
      addElement(reql_to_number(val));
      break;
    }
    case REQL_R_OBJECT: {
      startObject();

      ReQL_Iter_t it = reql_new_iter(val);
      ReQL_Obj_t *key = NULL;
      ReQL_Obj_t *value = NULL;

      while ((key = reql_iter_next(&it)) != NULL) {
        value = reql_object_get(val, key);
        std::string key_string((char *)reql_string_buf(key), reql_size(key));

        switch (reql_datum_type(value)) {
          case REQL_R_BOOL: {
            addKeyValue(key_string, static_cast<bool>(reql_to_bool(val)));
            break;
          }
          case REQL_R_ARRAY:
          case REQL_R_OBJECT: {
            addKey(key_string);
            parse(value);
            break;
          }
          case REQL_R_NULL: {
            addKeyValue(key_string);
            break;
          }
          case REQL_R_NUM: {
            addKeyValue(key_string, reql_to_number(value));
            break;
          }
          case REQL_R_JSON:
          case REQL_R_REQL: break;
          case REQL_R_STR: {
            addKeyValue(key_string, std::string((char *)reql_string_buf(value), reql_size(value)));
            break;
          }
        }
      }

      endObject();
      break;
    }
    case REQL_R_STR: {
      addElement(std::string((char *)reql_string_buf(val), reql_size(val)));
      break;
    }
  }
}

class ResultBuilder : public Parser {
public:
  Result result() { return p_result; }

private:
  void startObject() {
    p_stack.push_back(Result());
    p_stack.end()->type = REQL_R_OBJECT;
    p_stack.end()->value.object = std::map<std::string, Result>();
  }

  void addKey(std::string key) {
    p_keys.push_back(key);
  }

  void addKeyValue(std::string key) {
    Result res;
    res.type = REQL_R_NULL;
    p_stack.end()->value.object.insert({key, res});
  }

  void addKeyValue(std::string key, bool value) {
    Result res;
    res.type = REQL_R_BOOL;
    res.value.boolean = value;
    p_stack.end()->value.object.insert({key, res});
  }

  void addKeyValue(std::string key, double value) {
    Result res;
    res.type = REQL_R_NUM;
    res.value.num = value;
    p_stack.end()->value.object.insert({key, res});
  }

  void addKeyValue(std::string key, std::string value) {
    Result res;
    res.type = REQL_R_NULL;
    p_stack.end()->value.object.insert({key, res});
  }

  void endObject() {
    end();
  }

  void startArray() {
    p_stack.push_back(Result());
    p_stack.end()->type = REQL_R_ARRAY;
    p_stack.end()->value.array = std::vector<Result>();
  }

  void addElement() {
    Result res;
    res.type = REQL_R_NULL;
    addElement(std::move(res));
  }

  void addElement(bool value) {
    Result res;
    res.type = REQL_R_BOOL;
    res.value.boolean = value;
    addElement(std::move(res));
  }

  void addElement(double value) {
    Result res;
    res.type = REQL_R_NUM;
    res.value.num = value;
    addElement(std::move(res));
  }

  void addElement(std::string value) {
    Result res;
    res.type = REQL_R_STR;
    res.value.string = value;
    addElement(std::move(res));
  }

  void endArray() {
    end();
  }

  void addElement(Result &&val) {
    if (p_stack.empty()) {
      p_result = std::move(val);
    } else {
      std::vector<Result> *array = &p_stack.end()->value.array;
      array->insert(array->end(), std::move(val));
    }
  }

  void end() {
    Result last = *p_stack.end();
    p_stack.pop_back();
    if (p_stack.empty()) {
      p_result = last;
    } else if (p_stack.end()->type == REQL_R_OBJECT) {
      std::string key = *p_keys.end();
      p_keys.pop_back();
      p_stack.end()->value.object.insert({key, last});
    } else {
      addElement(std::move(last));
    }
  }

  std::vector<Result> p_stack;
  std::vector<std::string> p_keys;
  Result p_result;
};

Cursor::Cursor() : cur(new ReQL_Cur_t) {
  reql_cursor_init(data());
}

Cursor::~Cursor() {
}

bool Cursor::isOpen() const {
  return reql_cur_open(data());
}

Result
Cursor::next() {
  ResultBuilder builder;
  next(builder);
  return builder.result();
}

void
Cursor::next(Parser &p) {
  p.parse(reql_cursor_next(data()));
}

ReQL_Cur_t *
Cursor::data() const {
  return cur.get();
}

void
Cursor::close() {
}

Connection::Connection() : conn(new ReQL_Conn_t) {
  reql_connection_init(data());

  std::uint8_t buf[500];

  if (reql_connect(data(), buf, 500)) {
  }
}

Connection::Connection(const std::string &host) : conn(new ReQL_Conn_t) {
  reql_connection_init(data());

  reql_conn_set_addr(data(), (char *)host.c_str());

  std::uint8_t buf[500];

  if (reql_connect(data(), buf, 500)) {
  }
}

Connection::Connection(const std::string &host, const std::uint16_t &port) : conn(new ReQL_Conn_t) {
  reql_connection_init(data());

  reql_conn_set_addr(data(), (char *)host.c_str());
  reql_conn_set_port(data(), (char *)std::to_string(port).c_str());

  std::uint8_t buf[500];

  if (reql_connect(data(), buf, 500)) {
  }
}

Connection::Connection(const std::string &host, const std::uint16_t &port, const std::string &key) : conn(new ReQL_Conn_t) {
  reql_connection_init(data());

  if (key.size() > UINT32_MAX) {
  }

  std::uint32_t key_len = (std::uint32_t)key.size();

  reql_conn_set_addr(data(), (char *)host.c_str());
  reql_conn_set_port(data(), (char *)std::to_string(port).c_str());
  reql_conn_set_auth(data(), key_len, (char *)key.c_str());

  std::uint8_t buf[500];

  if (reql_connect(data(), buf, 500)) {
  }
}

Connection::Connection(const Connection &other) {
}

Connection::Connection(Connection &&other) {
  conn = std::move(other.conn);
}

Connection::~Connection() {
  reql_ensure_conn_close(data());
}

Connection &Connection::operator=(const Connection &other) {
  return *this;
}

Connection &Connection::operator=(Connection &&other) {
  conn = std::move(other.conn);
  return *this;
}

void
Connection::close() {
  reql_close_conn(data());
}

bool
Connection::isOpen() const {
  return reql_conn_open(data());
}

ReQL_Conn_t *
Connection::data() const {
  return conn.get();
}

Cursor Query::run(const Connection &conn) const {
  if (!conn.isOpen()) {
  }

  Cursor cur;

  ReQL kwargs;

  reql_run(cur.data(), p_query.data(), conn.data(), kwargs.data());

  return cur;
}

Query &Query::operator=(const Query &other) {
  Expr::operator=(other);
  return *this;
}

Query &Query::operator=(Query &&other) {
  Expr::operator=(std::move(other));
  return *this;
}

bool Query::operator<(const Query &other) const {
  return Expr::operator<(other);
}

}
<commit_msg>Add include for `memset`.<commit_after>/*
Copyright 2014-2015 Adam Grandquist

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.
 */
/**
 * @author Adam Grandquist
 * @copyright Apache
 */

#include "ReQL.hpp"

#include <cstring>

namespace ReQL {

Result::Result() : type(REQL_R_JSON) {}

Result::Result(const Result &other) {
  value.copy(other.value, type);
}

Result::Result(Result &&other) {
  value.move(std::move(other.value), type);
}

Result::~Result() {
  value.release(type);
}

Result &
Result::operator=(const Result &other) {
  if (this != &other) {
    value.copy(other.value, type);
  }
  return *this;
}

Result &
Result::operator=(Result &&other) {
  if (this != &other) {
    value.move(std::move(other.value), type);
  }
  return *this;
}

Result::JSON_Value::JSON_Value() {
  std::memset(this, 0, sizeof(Result::JSON_Value));
}

void
Result::JSON_Value::copy(const Result::JSON_Value &other, ReQL_Datum_t type) {
  switch (type) {
    case REQL_R_ARRAY: {
      array = other.array;
      break;
    }
    case REQL_R_BOOL: {
      boolean = other.boolean;
      break;
    }
    case REQL_R_NUM: {
      num = other.num;
      break;
    }
    case REQL_R_OBJECT: {
      object = other.object;
      break;
    }
    case REQL_R_STR: {
      string = other.string;
      break;
    }
    case REQL_R_NULL:
    case REQL_R_JSON:
    case REQL_R_REQL: break;
  }
}

void
Result::JSON_Value::move(Result::JSON_Value &&other, ReQL_Datum_t type) {
  switch (type) {
    case REQL_R_ARRAY: {
      array = std::move(other.array);
      break;
    }
    case REQL_R_BOOL: {
      boolean = std::move(other.boolean);
      break;
    }
    case REQL_R_NUM: {
      num = std::move(other.num);
      break;
    }
    case REQL_R_OBJECT: {
      object = std::move(other.object);
      break;
    }
    case REQL_R_STR: {
      string = std::move(other.string);
      break;
    }
    case REQL_R_NULL:
    case REQL_R_JSON:
    case REQL_R_REQL: break;
  }
}

void
Result::JSON_Value::release(ReQL_Datum_t type) {
  switch (type) {
    case REQL_R_ARRAY: {
      array.~vector();
      break;
    }
    case REQL_R_OBJECT: {
      object.~map();
      break;
    }
    case REQL_R_STR: {
      string.~basic_string();
      break;
    }
    case REQL_R_BOOL:
    case REQL_R_JSON:
    case REQL_R_NULL:
    case REQL_R_NUM:
    case REQL_R_REQL: break;
  }
}

Result::JSON_Value::~JSON_Value() {
  std::memset(this, 0, sizeof(Result::JSON_Value));
}

void
Parser::parse(ReQL_Obj_t *val) {
  switch (reql_datum_type(val)) {
    case REQL_R_ARRAY: {
      startArray();

      ReQL_Iter_t it = reql_new_iter(val);
      ReQL_Obj_t *elem = NULL;

      while ((elem = reql_iter_next(&it)) != NULL) {
        parse(elem);
      }

      endArray();
      break;
    }
    case REQL_R_BOOL: {
      addElement(static_cast<bool>(reql_to_bool(val)));
      break;
    }
    case REQL_R_JSON:
    case REQL_R_REQL: break;
    case REQL_R_NULL: {
      addElement();
      break;
    }
    case REQL_R_NUM: {
      addElement(reql_to_number(val));
      break;
    }
    case REQL_R_OBJECT: {
      startObject();

      ReQL_Iter_t it = reql_new_iter(val);
      ReQL_Obj_t *key = NULL;
      ReQL_Obj_t *value = NULL;

      while ((key = reql_iter_next(&it)) != NULL) {
        value = reql_object_get(val, key);
        std::string key_string((char *)reql_string_buf(key), reql_size(key));

        switch (reql_datum_type(value)) {
          case REQL_R_BOOL: {
            addKeyValue(key_string, static_cast<bool>(reql_to_bool(val)));
            break;
          }
          case REQL_R_ARRAY:
          case REQL_R_OBJECT: {
            addKey(key_string);
            parse(value);
            break;
          }
          case REQL_R_NULL: {
            addKeyValue(key_string);
            break;
          }
          case REQL_R_NUM: {
            addKeyValue(key_string, reql_to_number(value));
            break;
          }
          case REQL_R_JSON:
          case REQL_R_REQL: break;
          case REQL_R_STR: {
            addKeyValue(key_string, std::string((char *)reql_string_buf(value), reql_size(value)));
            break;
          }
        }
      }

      endObject();
      break;
    }
    case REQL_R_STR: {
      addElement(std::string((char *)reql_string_buf(val), reql_size(val)));
      break;
    }
  }
}

class ResultBuilder : public Parser {
public:
  Result result() { return p_result; }

private:
  void startObject() {
    p_stack.push_back(Result());
    p_stack.end()->type = REQL_R_OBJECT;
    p_stack.end()->value.object = std::map<std::string, Result>();
  }

  void addKey(std::string key) {
    p_keys.push_back(key);
  }

  void addKeyValue(std::string key) {
    Result res;
    res.type = REQL_R_NULL;
    p_stack.end()->value.object.insert({key, res});
  }

  void addKeyValue(std::string key, bool value) {
    Result res;
    res.type = REQL_R_BOOL;
    res.value.boolean = value;
    p_stack.end()->value.object.insert({key, res});
  }

  void addKeyValue(std::string key, double value) {
    Result res;
    res.type = REQL_R_NUM;
    res.value.num = value;
    p_stack.end()->value.object.insert({key, res});
  }

  void addKeyValue(std::string key, std::string value) {
    Result res;
    res.type = REQL_R_NULL;
    p_stack.end()->value.object.insert({key, res});
  }

  void endObject() {
    end();
  }

  void startArray() {
    p_stack.push_back(Result());
    p_stack.end()->type = REQL_R_ARRAY;
    p_stack.end()->value.array = std::vector<Result>();
  }

  void addElement() {
    Result res;
    res.type = REQL_R_NULL;
    addElement(std::move(res));
  }

  void addElement(bool value) {
    Result res;
    res.type = REQL_R_BOOL;
    res.value.boolean = value;
    addElement(std::move(res));
  }

  void addElement(double value) {
    Result res;
    res.type = REQL_R_NUM;
    res.value.num = value;
    addElement(std::move(res));
  }

  void addElement(std::string value) {
    Result res;
    res.type = REQL_R_STR;
    res.value.string = value;
    addElement(std::move(res));
  }

  void endArray() {
    end();
  }

  void addElement(Result &&val) {
    if (p_stack.empty()) {
      p_result = std::move(val);
    } else {
      std::vector<Result> *array = &p_stack.end()->value.array;
      array->insert(array->end(), std::move(val));
    }
  }

  void end() {
    Result last = *p_stack.end();
    p_stack.pop_back();
    if (p_stack.empty()) {
      p_result = last;
    } else if (p_stack.end()->type == REQL_R_OBJECT) {
      std::string key = *p_keys.end();
      p_keys.pop_back();
      p_stack.end()->value.object.insert({key, last});
    } else {
      addElement(std::move(last));
    }
  }

  std::vector<Result> p_stack;
  std::vector<std::string> p_keys;
  Result p_result;
};

Cursor::Cursor() : cur(new ReQL_Cur_t) {
  reql_cursor_init(data());
}

Cursor::~Cursor() {
}

bool Cursor::isOpen() const {
  return reql_cur_open(data());
}

Result
Cursor::next() {
  ResultBuilder builder;
  next(builder);
  return builder.result();
}

void
Cursor::next(Parser &p) {
  p.parse(reql_cursor_next(data()));
}

ReQL_Cur_t *
Cursor::data() const {
  return cur.get();
}

void
Cursor::close() {
}

Connection::Connection() : conn(new ReQL_Conn_t) {
  reql_connection_init(data());

  std::uint8_t buf[500];

  if (reql_connect(data(), buf, 500)) {
  }
}

Connection::Connection(const std::string &host) : conn(new ReQL_Conn_t) {
  reql_connection_init(data());

  reql_conn_set_addr(data(), (char *)host.c_str());

  std::uint8_t buf[500];

  if (reql_connect(data(), buf, 500)) {
  }
}

Connection::Connection(const std::string &host, const std::uint16_t &port) : conn(new ReQL_Conn_t) {
  reql_connection_init(data());

  reql_conn_set_addr(data(), (char *)host.c_str());
  reql_conn_set_port(data(), (char *)std::to_string(port).c_str());

  std::uint8_t buf[500];

  if (reql_connect(data(), buf, 500)) {
  }
}

Connection::Connection(const std::string &host, const std::uint16_t &port, const std::string &key) : conn(new ReQL_Conn_t) {
  reql_connection_init(data());

  if (key.size() > UINT32_MAX) {
  }

  std::uint32_t key_len = (std::uint32_t)key.size();

  reql_conn_set_addr(data(), (char *)host.c_str());
  reql_conn_set_port(data(), (char *)std::to_string(port).c_str());
  reql_conn_set_auth(data(), key_len, (char *)key.c_str());

  std::uint8_t buf[500];

  if (reql_connect(data(), buf, 500)) {
  }
}

Connection::Connection(const Connection &other) {
}

Connection::Connection(Connection &&other) {
  conn = std::move(other.conn);
}

Connection::~Connection() {
  reql_ensure_conn_close(data());
}

Connection &Connection::operator=(const Connection &other) {
  return *this;
}

Connection &Connection::operator=(Connection &&other) {
  conn = std::move(other.conn);
  return *this;
}

void
Connection::close() {
  reql_close_conn(data());
}

bool
Connection::isOpen() const {
  return reql_conn_open(data());
}

ReQL_Conn_t *
Connection::data() const {
  return conn.get();
}

Cursor Query::run(const Connection &conn) const {
  if (!conn.isOpen()) {
  }

  Cursor cur;

  ReQL kwargs;

  reql_run(cur.data(), p_query.data(), conn.data(), kwargs.data());

  return cur;
}

Query &Query::operator=(const Query &other) {
  Expr::operator=(other);
  return *this;
}

Query &Query::operator=(Query &&other) {
  Expr::operator=(std::move(other));
  return *this;
}

bool Query::operator<(const Query &other) const {
  return Expr::operator<(other);
}

}
<|endoftext|>


<commit_before>#include "Sign.h"

Sign::Sign(void){

  uint8_t lengths[LETTERS_COUNT][16] = {
    {3, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 2, 2},
    {2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 2, 2},
    {2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 2, 2},
    {2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 2, 2}
  };

  for(uint16_t i=0; i < LETTERS_COUNT; i++){
    letters[i] = new Letter(lengths[i]);
    for(uint16_t j=0; j<16; j++){
      segments[(i*16)+j] = letters[i] -> segments[j];
    }
  }
  //uint16_t pixel_count = this -> pixelCount();

  characters[0] = 'D';
  characters[1] = 'A';
  characters[2] = 'D';
  characters[3] = 'A';
};

void Sign::pushChar(char character){
  this -> pushChar(character, false);
}
void Sign::pushChar(char character, bool shouldPrint){
  if( shouldPrint ){
    Serial.print(character);
    Serial1.print(character);
  }
  if( binarySegsForChar(character) == 0xFFFF ){ return; }

  for(uint8_t i=0; i< LETTERS_COUNT - 1; i++){
    characters[i] = characters[i+1];
  }
  characters[LETTERS_COUNT-1] = character;

  this -> sanitize();

  for(uint8_t i=0; i< LETTERS_COUNT; i++){
    letters[i] -> currentChar = characters[i];
  }
}

void Sign::setCharacters(){
  for(uint8_t i=0; i<LETTERS_COUNT; i++){
    this -> letters[i] -> setChar(characters[i]);
  }
}

void Sign::setLayer(uint8_t layer, bool isOn){
  for(uint8_t i=0; i<LETTERS_COUNT; i++){
    letters[i] -> setLayer(layer, isOn);
  }
}

void Sign::setWord(String word){
  uint8_t size = min((uint8_t)word.length(), LETTERS_COUNT);

  for(uint8_t i=0; i<size; i++){
    characters[i] = word.charAt(i);
  }
  this -> sanitize();

  for(uint8_t i=0; i<size; i++){
    letters[i] -> setChar( characters[i] );
  }
}

void Sign::_setWord(String word, uint8_t size){
  char ctr;
  for(uint8_t i=0; i< size; i++){
    ctr = word.charAt(i);
    characters[i] = ctr;
    letters[i] -> setChar( ctr );
  }
}

#define BAD_WORDS_COUNT 18
const String badWords[BAD_WORDS_COUNT] = {
  //"TEST"
  "CUNT", "GOOK", "FUCK", "SHIT", "FAGG",
  "FAG ", " FAG", "COON", "HEEB", "SLUT",
  "COON", "KKK ", " KKK", "KYKE", "SPIC",
  "SPIK", "TWAT", "HOMO"
};

void Sign::sanitize(){
  String ctrs = String(characters).substring(0, LETTERS_COUNT);
  String badWord;
  for(uint8_t i=0; i< BAD_WORDS_COUNT; i++){
    badWord = badWords[i];
    if(badWord.equalsIgnoreCase(ctrs)){
      this -> _setWord(String("LOVE"), LETTERS_COUNT);
    }
  }
}

uint16_t Sign::pixelCount(){

  if(_pixel_count > 0){
    return _pixel_count;
  }

  uint16_t pixel_count = 0;
  for(uint8_t i = 0; i < LETTERS_COUNT; i++){
    pixel_count += letters[i]->pixelCount();
  }
  _pixel_count = pixel_count;
  return pixel_count;
}

uint8_t Sign::letterCount(){
  return LETTERS_COUNT;
}

uint16_t Sign::segmentCount(){
  return 16*LETTERS_COUNT;
}
<commit_msg>Remove SHIT and FUCK from bad words list<commit_after>#include "Sign.h"

Sign::Sign(void){

  uint8_t lengths[LETTERS_COUNT][16] = {
    {3, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 2, 2},
    {2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 2, 2},
    {2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 2, 2},
    {2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 2, 2}
  };

  for(uint16_t i=0; i < LETTERS_COUNT; i++){
    letters[i] = new Letter(lengths[i]);
    for(uint16_t j=0; j<16; j++){
      segments[(i*16)+j] = letters[i] -> segments[j];
    }
  }
  //uint16_t pixel_count = this -> pixelCount();

  characters[0] = 'D';
  characters[1] = 'A';
  characters[2] = 'D';
  characters[3] = 'A';
};

void Sign::pushChar(char character){
  this -> pushChar(character, false);
}
void Sign::pushChar(char character, bool shouldPrint){
  if( shouldPrint ){
    Serial.print(character);
    Serial1.print(character);
  }
  if( binarySegsForChar(character) == 0xFFFF ){ return; }

  for(uint8_t i=0; i< LETTERS_COUNT - 1; i++){
    characters[i] = characters[i+1];
  }
  characters[LETTERS_COUNT-1] = character;

  this -> sanitize();

  for(uint8_t i=0; i< LETTERS_COUNT; i++){
    letters[i] -> currentChar = characters[i];
  }
}

void Sign::setCharacters(){
  for(uint8_t i=0; i<LETTERS_COUNT; i++){
    this -> letters[i] -> setChar(characters[i]);
  }
}

void Sign::setLayer(uint8_t layer, bool isOn){
  for(uint8_t i=0; i<LETTERS_COUNT; i++){
    letters[i] -> setLayer(layer, isOn);
  }
}

void Sign::setWord(String word){
  uint8_t size = min((uint8_t)word.length(), LETTERS_COUNT);

  for(uint8_t i=0; i<size; i++){
    characters[i] = word.charAt(i);
  }
  this -> sanitize();

  for(uint8_t i=0; i<size; i++){
    letters[i] -> setChar( characters[i] );
  }
}

void Sign::_setWord(String word, uint8_t size){
  char ctr;
  for(uint8_t i=0; i< size; i++){
    ctr = word.charAt(i);
    characters[i] = ctr;
    letters[i] -> setChar( ctr );
  }
}

#define BAD_WORDS_COUNT 16
const String badWords[BAD_WORDS_COUNT] = {
  //"TEST"
  "CUNT", "GOOK", "FAGG",
  "FAG ", " FAG", "COON", "HEEB", "SLUT",
  "COON", "KKK ", " KKK", "KYKE", "SPIC",
  "SPIK", "TWAT", "HOMO"
};

void Sign::sanitize(){
  String ctrs = String(characters).substring(0, LETTERS_COUNT);
  String badWord;
  for(uint8_t i=0; i< BAD_WORDS_COUNT; i++){
    badWord = badWords[i];
    if(badWord.equalsIgnoreCase(ctrs)){
      this -> _setWord(String("LOVE"), LETTERS_COUNT);
    }
  }
}

uint16_t Sign::pixelCount(){

  if(_pixel_count > 0){
    return _pixel_count;
  }

  uint16_t pixel_count = 0;
  for(uint8_t i = 0; i < LETTERS_COUNT; i++){
    pixel_count += letters[i]->pixelCount();
  }
  _pixel_count = pixel_count;
  return pixel_count;
}

uint8_t Sign::letterCount(){
  return LETTERS_COUNT;
}

uint16_t Sign::segmentCount(){
  return 16*LETTERS_COUNT;
}
<|endoftext|>


<commit_before>// cc.in79
// problem with templatized forward decl?
// no, was a problem with templatized prototypes

class istream;

template<class TP> class smanip;
//template<class TP> class smanip {};

template<class TP>
inline istream& operator>>(istream& i, const smanip<TP>& m);
//int foo(smanip<TP> &m);

typedef smanip<int> smanip_int;

template<class TP> class smanip {
  smanip *whatever;
  smanip<TP> *whatever2;
};

void f()
{
  smanip_int s;
  s.whatever;
}

<commit_msg>Fix gcc compilation issue, thanks to Evan Driscoll.<commit_after>// in/t0079.cc
// problem with templatized forward decl?
// no, was a problem with templatized prototypes

class istream;

template<class TP> class smanip;
//template<class TP> class smanip {};

template<class TP>
inline istream& operator>>(istream& i, const smanip<TP>& m);
//int foo(smanip<TP> &m);

typedef smanip<int> smanip_int;

template<class TP> class smanip {
public:
  smanip *whatever;
  smanip<TP> *whatever2;
};

void f()
{
  smanip_int s;
  s.whatever;
}

<|endoftext|>


<commit_before>/* This file is part of VoltDB.
 * Copyright (C) 2008-2013 VoltDB Inc.
 *
 * This file contains original code and/or modifications of original code.
 * Any modifications made by VoltDB Inc. are licensed under the following
 * terms and conditions:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with VoltDB.  If not, see <http://www.gnu.org/licenses/>.
 */
/* Copyright (C) 2008 by H-Store Project
 * Brown University
 * Massachusetts Institute of Technology
 * Yale University
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include <iostream>
#include "seqscanexecutor.h"
#include "common/debuglog.h"
#include "common/common.h"
#include "common/tabletuple.h"
#include "common/FatalException.hpp"
#include "expressions/abstractexpression.h"
#include "plannodes/seqscannode.h"
#include "plannodes/projectionnode.h"
#include "plannodes/limitnode.h"
#include "storage/table.h"
#include "storage/temptable.h"
#include "storage/tablefactory.h"
#include "storage/tableiterator.h"

using namespace voltdb;

bool SeqScanExecutor::p_init(AbstractPlanNode* abstract_node,
                             TempTableLimits* limits)
{
    VOLT_TRACE("init SeqScan Executor");

    SeqScanPlanNode* node = dynamic_cast<SeqScanPlanNode*>(abstract_node);
    assert(node);
    assert(node->isSubQuery() || node->getTargetTable());
    assert((node->isSubQuery() && node->getChildren().size() == 1) ||
        !node->isSubQuery());

    //
    // OPTIMIZATION: If there is no predicate for this SeqScan,
    // then we want to just set our OutputTable pointer to be the
    // pointer of our TargetTable. This prevents us from just
    // reading through the entire TargetTable and copying all of
    // the tuples. We are guarenteed that no Executor will ever
    // modify an input table, so this operation is safe
    //
    if (!this->needsOutputTableClear())
    {
        node->setOutputTable(node->getTargetTable());
    }
    //
    // Otherwise create a new temp table that mirrors the
    // output schema specified in the plan (which should mirror
    // the output schema for any inlined projection)
    //
    else
    {
        // Create output table based on output schema from the plan
        const std::string& temp_name = (!node->isSubQuery()) ?
            node->getTargetTable()->name() :
            node->getChildren()[0]->getOutputTable()->name();
        setTempOutputTable(limits, temp_name);
    }
    return true;
}

bool SeqScanExecutor::needsOutputTableClear() {
    // clear the temporary output table only when it has a predicate.
    // if it doesn't have a predicate, it's the original persistent table
    // and we don't have to (and must not) clear it.
    SeqScanPlanNode* node = dynamic_cast<SeqScanPlanNode*>(m_abstractNode);
    assert(node);
    return node->needsOutputTableClear();
}

bool SeqScanExecutor::p_execute(const NValueArray &params) {
    SeqScanPlanNode* node = dynamic_cast<SeqScanPlanNode*>(m_abstractNode);
    assert(node);
    Table* output_table = node->getOutputTable();
    assert(output_table);

    Table* input_table = (!node->isSubQuery()) ?
        dynamic_cast<Table*>(node->getTargetTable()) :
        node->getChildren()[0]->getOutputTable();

    assert(input_table);
    //cout << "SeqScanExecutor: node id" << node->getPlanNodeId() << endl;
    VOLT_TRACE("Sequential Scanning table :\n %s",
               input_table->debug().c_str());
    VOLT_DEBUG("Sequential Scanning table : %s which has %d active, %d"
               " allocated",
               input_table->name().c_str(),
               (int)input_table->activeTupleCount(),
               (int)input_table->allocatedTupleCount());

    //
    // OPTIMIZATION: NESTED PROJECTION
    //
    // Since we have the input params, we need to call substitute to
    // change any nodes in our expression tree to be ready for the
    // projection operations in execute
    //
    int num_of_columns = (int)output_table->columnCount();
    ProjectionPlanNode* projection_node = dynamic_cast<ProjectionPlanNode*>(node->getInlinePlanNode(PLAN_NODE_TYPE_PROJECTION));
    if (projection_node != NULL) {
        for (int ctr = 0; ctr < num_of_columns; ctr++) {
            assert(projection_node->getOutputColumnExpressions()[ctr]);
            projection_node->getOutputColumnExpressions()[ctr]->substitute(params);
        }
    }

    //
    // OPTIMIZATION: NESTED LIMIT
    // How nice! We can also cut off our scanning with a nested limit!
    //
    LimitPlanNode* limit_node = dynamic_cast<LimitPlanNode*>(node->getInlinePlanNode(PLAN_NODE_TYPE_LIMIT));

    //
    // OPTIMIZATION:
    //
    // If there is no predicate and no Projection for this SeqScan,
    // then we have already set the node's OutputTable to just point
    // at the TargetTable. Therefore, there is nothing we more we need
    // to do here
    //
    if (node->getPredicate() != NULL || projection_node != NULL ||
        limit_node != NULL)
    {
        //
        // Just walk through the table using our iterator and apply
        // the predicate to each tuple. For each tuple that satisfies
        // our expression, we'll insert them into the output table.
        //
        TableTuple tuple(input_table->schema());
        TableIterator iterator = input_table->iterator();
        AbstractExpression *predicate = node->getPredicate();

        if (predicate)
        {
            VOLT_TRACE("SCAN PREDICATE A:\n%s\n", predicate->debug(true).c_str());
            predicate->substitute(params);
            assert(predicate != NULL);
            VOLT_DEBUG("SCAN PREDICATE B:\n%s\n",
                       predicate->debug(true).c_str());
        }

        int limit = -1;
        int offset = -1;
        if (limit_node) {
            limit_node->getLimitAndOffsetByReference(params, limit, offset);
        }

        int tuple_ctr = 0;
        int tuple_skipped = 0;
        m_engine->setLastAccessedTable(target_table);
        while ((limit == -1 || tuple_ctr < limit) && iterator.next(tuple))
        {
            VOLT_TRACE("INPUT TUPLE: %s, %d/%d\n",
                       tuple.debug(input_table->name()).c_str(), tuple_ctr,
                       (int)input_table->activeTupleCount());
            m_engine->noteTuplesProcessedForProgressMonitoring(1);
            //
            // For each tuple we need to evaluate it against our predicate
            //
            if (predicate == NULL || predicate->eval(&tuple, NULL).isTrue())
            {
                // Check if we have to skip this tuple because of offset
                if (tuple_skipped < offset) {
                    tuple_skipped++;
                    continue;
                }
                ++tuple_ctr;

                //
                // Nested Projection
                // Project (or replace) values from input tuple
                //
                if (projection_node != NULL)
                {
                    TableTuple &temp_tuple = output_table->tempTuple();
                    for (int ctr = 0; ctr < num_of_columns; ctr++)
                    {
                        NValue value =
                            projection_node->
                          getOutputColumnExpressions()[ctr]->eval(&tuple, NULL);
                        temp_tuple.setNValue(ctr, value);
                    }
                    if (!output_table->insertTuple(temp_tuple))
                    {
                        VOLT_ERROR("Failed to insert tuple from table '%s' into"
                                   " output table '%s'",
                                   input_table->name().c_str(),
                                   output_table->name().c_str());
                        return false;
                    }
                }
                else
                {
                    //
                    // Insert the tuple into our output table
                    //
                    if (!output_table->insertTuple(tuple)) {
                        VOLT_ERROR("Failed to insert tuple from table '%s' into"
                                   " output table '%s'",
                                   input_table->name().c_str(),
                                   output_table->name().c_str());
                        return false;
                    }
                }
            }
        }
    }
    VOLT_TRACE("\n%s\n", output_table->debug().c_str());
    VOLT_DEBUG("Finished Seq scanning");

    return true;
}
<commit_msg>Fixed merge error<commit_after>/* This file is part of VoltDB.
 * Copyright (C) 2008-2013 VoltDB Inc.
 *
 * This file contains original code and/or modifications of original code.
 * Any modifications made by VoltDB Inc. are licensed under the following
 * terms and conditions:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with VoltDB.  If not, see <http://www.gnu.org/licenses/>.
 */
/* Copyright (C) 2008 by H-Store Project
 * Brown University
 * Massachusetts Institute of Technology
 * Yale University
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include <iostream>
#include "seqscanexecutor.h"
#include "common/debuglog.h"
#include "common/common.h"
#include "common/tabletuple.h"
#include "common/FatalException.hpp"
#include "expressions/abstractexpression.h"
#include "plannodes/seqscannode.h"
#include "plannodes/projectionnode.h"
#include "plannodes/limitnode.h"
#include "storage/table.h"
#include "storage/temptable.h"
#include "storage/tablefactory.h"
#include "storage/tableiterator.h"

using namespace voltdb;

bool SeqScanExecutor::p_init(AbstractPlanNode* abstract_node,
                             TempTableLimits* limits)
{
    VOLT_TRACE("init SeqScan Executor");

    SeqScanPlanNode* node = dynamic_cast<SeqScanPlanNode*>(abstract_node);
    assert(node);
    assert(node->isSubQuery() || node->getTargetTable());
    assert((node->isSubQuery() && node->getChildren().size() == 1) ||
        !node->isSubQuery());

    //
    // OPTIMIZATION: If there is no predicate for this SeqScan,
    // then we want to just set our OutputTable pointer to be the
    // pointer of our TargetTable. This prevents us from just
    // reading through the entire TargetTable and copying all of
    // the tuples. We are guarenteed that no Executor will ever
    // modify an input table, so this operation is safe
    //
    if (!this->needsOutputTableClear())
    {
        node->setOutputTable(node->getTargetTable());
    }
    //
    // Otherwise create a new temp table that mirrors the
    // output schema specified in the plan (which should mirror
    // the output schema for any inlined projection)
    //
    else
    {
        // Create output table based on output schema from the plan
        const std::string& temp_name = (!node->isSubQuery()) ?
            node->getTargetTable()->name() :
            node->getChildren()[0]->getOutputTable()->name();
        setTempOutputTable(limits, temp_name);
    }
    return true;
}

bool SeqScanExecutor::needsOutputTableClear() {
    // clear the temporary output table only when it has a predicate.
    // if it doesn't have a predicate, it's the original persistent table
    // and we don't have to (and must not) clear it.
    SeqScanPlanNode* node = dynamic_cast<SeqScanPlanNode*>(m_abstractNode);
    assert(node);
    return node->needsOutputTableClear();
}

bool SeqScanExecutor::p_execute(const NValueArray &params) {
    SeqScanPlanNode* node = dynamic_cast<SeqScanPlanNode*>(m_abstractNode);
    assert(node);
    Table* output_table = node->getOutputTable();
    assert(output_table);

    Table* input_table = (!node->isSubQuery()) ?
        dynamic_cast<Table*>(node->getTargetTable()) :
        node->getChildren()[0]->getOutputTable();

    assert(input_table);
    //cout << "SeqScanExecutor: node id" << node->getPlanNodeId() << endl;
    VOLT_TRACE("Sequential Scanning table :\n %s",
               input_table->debug().c_str());
    VOLT_DEBUG("Sequential Scanning table : %s which has %d active, %d"
               " allocated",
               input_table->name().c_str(),
               (int)input_table->activeTupleCount(),
               (int)input_table->allocatedTupleCount());

    //
    // OPTIMIZATION: NESTED PROJECTION
    //
    // Since we have the input params, we need to call substitute to
    // change any nodes in our expression tree to be ready for the
    // projection operations in execute
    //
    int num_of_columns = (int)output_table->columnCount();
    ProjectionPlanNode* projection_node = dynamic_cast<ProjectionPlanNode*>(node->getInlinePlanNode(PLAN_NODE_TYPE_PROJECTION));
    if (projection_node != NULL) {
        for (int ctr = 0; ctr < num_of_columns; ctr++) {
            assert(projection_node->getOutputColumnExpressions()[ctr]);
            projection_node->getOutputColumnExpressions()[ctr]->substitute(params);
        }
    }

    //
    // OPTIMIZATION: NESTED LIMIT
    // How nice! We can also cut off our scanning with a nested limit!
    //
    LimitPlanNode* limit_node = dynamic_cast<LimitPlanNode*>(node->getInlinePlanNode(PLAN_NODE_TYPE_LIMIT));

    //
    // OPTIMIZATION:
    //
    // If there is no predicate and no Projection for this SeqScan,
    // then we have already set the node's OutputTable to just point
    // at the TargetTable. Therefore, there is nothing we more we need
    // to do here
    //
    if (node->getPredicate() != NULL || projection_node != NULL ||
        limit_node != NULL)
    {
        //
        // Just walk through the table using our iterator and apply
        // the predicate to each tuple. For each tuple that satisfies
        // our expression, we'll insert them into the output table.
        //
        TableTuple tuple(input_table->schema());
        TableIterator iterator = input_table->iterator();
        AbstractExpression *predicate = node->getPredicate();

        if (predicate)
        {
            VOLT_TRACE("SCAN PREDICATE A:\n%s\n", predicate->debug(true).c_str());
            predicate->substitute(params);
            assert(predicate != NULL);
            VOLT_DEBUG("SCAN PREDICATE B:\n%s\n",
                       predicate->debug(true).c_str());
        }

        int limit = -1;
        int offset = -1;
        if (limit_node) {
            limit_node->getLimitAndOffsetByReference(params, limit, offset);
        }

        int tuple_ctr = 0;
        int tuple_skipped = 0;
        if (!node->isSubQuery()) {
            // Input table is the target table in this case
            m_engine->setLastAccessedTable(input_table);
        }
        while ((limit == -1 || tuple_ctr < limit) && iterator.next(tuple))
        {
            VOLT_TRACE("INPUT TUPLE: %s, %d/%d\n",
                       tuple.debug(input_table->name()).c_str(), tuple_ctr,
                       (int)input_table->activeTupleCount());
            m_engine->noteTuplesProcessedForProgressMonitoring(1);
            //
            // For each tuple we need to evaluate it against our predicate
            //
            if (predicate == NULL || predicate->eval(&tuple, NULL).isTrue())
            {
                // Check if we have to skip this tuple because of offset
                if (tuple_skipped < offset) {
                    tuple_skipped++;
                    continue;
                }
                ++tuple_ctr;

                //
                // Nested Projection
                // Project (or replace) values from input tuple
                //
                if (projection_node != NULL)
                {
                    TableTuple &temp_tuple = output_table->tempTuple();
                    for (int ctr = 0; ctr < num_of_columns; ctr++)
                    {
                        NValue value =
                            projection_node->
                          getOutputColumnExpressions()[ctr]->eval(&tuple, NULL);
                        temp_tuple.setNValue(ctr, value);
                    }
                    if (!output_table->insertTuple(temp_tuple))
                    {
                        VOLT_ERROR("Failed to insert tuple from table '%s' into"
                                   " output table '%s'",
                                   input_table->name().c_str(),
                                   output_table->name().c_str());
                        return false;
                    }
                }
                else
                {
                    //
                    // Insert the tuple into our output table
                    //
                    if (!output_table->insertTuple(tuple)) {
                        VOLT_ERROR("Failed to insert tuple from table '%s' into"
                                   " output table '%s'",
                                   input_table->name().c_str(),
                                   output_table->name().c_str());
                        return false;
                    }
                }
            }
        }
    }
    VOLT_TRACE("\n%s\n", output_table->debug().c_str());
    VOLT_DEBUG("Finished Seq scanning");

    return true;
}
<|endoftext|>


<commit_before><commit_msg>Move Upsample code to keep alphabetical op order<commit_after><|endoftext|>


<commit_before><commit_msg>PWM cleanup FIFO access<commit_after><|endoftext|>