#ifndef PGSQL_COL_H
#define PGSQL_COL_H

#include "Pgsql_Row.h"
#include <boost/container/small_vector.hpp>

namespace Pgsql {

	class Col {
	public:
		explicit Col(const Pgsql::Row &r)
			: row(r)
		{}

		void reset() { col = -1; }

		Pgsql::Value nextValue()
		{
			return row.get(++col);
		}

        void skip(int n = 1)
        {
            col += n;
        }

		template <typename E, typename I>
		Col& getAsArray(I insert_iter, NullHandling nullhandling = NullHandling::Throw)
		{
			nextValue().getAsArray<E, I>(insert_iter, nullhandling);
			return *this;
		}

		template <typename E, typename I>
		Col& getAsArray(I insert_iter, const E &value_for_nulls)
		{
			nextValue().getAsArray<E, I>(insert_iter, value_for_nulls);
			return *this;
		}

		template <typename E, typename I>
		Col& getAsArrayOfOptional(I insert_iter)
		{
			nextValue().getAsArrayOfOptional<E, I>(insert_iter);
			return *this;
		}

		template <typename E, typename I>
		Col& getAsVector(I insert_iter)
		{
			nextValue().getAsVector<E, I>(insert_iter);
			return *this;
		}
	private:
		const Pgsql::Row &row;
		int col = -1;
	};

	template <typename T>
	Col& operator>>(Col &c, std::vector<T> &s)
	{
		return c.getAsArray<T>(std::back_inserter(s));
	}

	template <typename T, std::size_t N>
	Col& operator>>(Col &c, boost::container::small_vector<T, N> &s)
	{
		return c.getAsArray<T>(std::back_inserter(s));
	}

	template <typename T>
	Col& operator>>(Col &c, T &s)
	{
		s << c.nextValue();
		return c;
	}


} // end namespace Pgsql

#endif // PGSQL_COL_H
