/*! \param in In-Stream to load the rank_support data from.
  */
 void load(std::istream& in) {
     m_abs_samples.load(in);
     m_differences.load(in);
     read_member(m_ones, in);
     read_member(m_size, in);
     m_contains_abs_sample.load(in);
     m_rank_contains_abs_sample.load(in, &m_contains_abs_sample);
 }
	//! Copy constructor
	nearest_neighbour_dictionary(const nearest_neighbour_dictionary& nnd)
		: m_abs_samples(nnd.m_abs_samples)
		, m_differences(nnd.m_differences)
		, m_ones(nnd.m_ones)
		, m_size(nnd.m_size)
		, m_contains_abs_sample(nnd.m_contains_abs_sample)
		, m_rank_contains_abs_sample(nnd.m_rank_contains_abs_sample)
	{
		m_rank_contains_abs_sample.set_vector(&m_contains_abs_sample);
	}
 void copy(const nearest_neighbour_dictionary& nnd) {
     // copy all members of the data structure
     m_abs_samples 	= 		nnd.m_abs_samples;
     m_differences 	= 		nnd.m_differences;
     m_ones 			= 		nnd.m_ones;
     m_size			= 		nnd.m_size;
     m_contains_abs_sample =	nnd.m_contains_abs_sample;
     m_rank_contains_abs_sample = nnd.m_rank_contains_abs_sample;
     m_rank_contains_abs_sample.set_vector(&m_contains_abs_sample);
 }
	void CEREAL_LOAD_FUNCTION_NAME(archive_t & ar)
	{
		ar(CEREAL_NVP(m_ones));
		ar(CEREAL_NVP(m_size));
		ar(CEREAL_NVP(m_abs_samples));
		ar(CEREAL_NVP(m_differences));
		ar(CEREAL_NVP(m_contains_abs_sample));
		ar(CEREAL_NVP(m_rank_contains_abs_sample));
		m_rank_contains_abs_sample.set_vector(&m_contains_abs_sample);
	}
 /*! \param out Out-Stream to serialize the data to.
 */
 size_type serialize(std::ostream& out, structure_tree_node* v=NULL, std::string name="")const {
     size_type written_bytes = 0;
     structure_tree_node* child = structure_tree::add_child(v, name, util::class_name(*this));
     written_bytes += m_abs_samples.serialize(out, child, "absolute_samples");
     written_bytes += m_differences.serialize(out, child, "differences");
     written_bytes += write_member(m_ones, out, child, "ones");
     written_bytes += write_member(m_size,out,  child, "size");
     written_bytes += m_contains_abs_sample.serialize(out, child, "contains_abs_sample");
     written_bytes += m_rank_contains_abs_sample.serialize(out, child, "rank_contains_abs_sample");
     structure_tree::add_size(child, written_bytes);
     return written_bytes;
 }
	nearest_neighbour_dictionary& operator=(nearest_neighbour_dictionary&& nnd)
	{
		if (this != &nnd) {
			m_abs_samples			   = std::move(nnd.m_abs_samples);
			m_differences			   = std::move(nnd.m_differences);
			m_ones					   = std::move(nnd.m_ones);
			m_size					   = std::move(nnd.m_size);
			m_contains_abs_sample	  = std::move(nnd.m_contains_abs_sample);
			m_rank_contains_abs_sample = std::move(nnd.m_rank_contains_abs_sample);
			m_rank_contains_abs_sample.set_vector(&m_contains_abs_sample);
		}
		return *this;
	}
	/*! \param idx Argument for the length of the prefix v[0..idx-1].
         *  \return Number of 1-bits in the prefix [0..idx-1] of the supported bit_vector.
         *  \par Time complexity \f$ \Order{1} \f$
         */
	size_type rank(size_type idx) const
	{
		assert(idx <= m_size);
		size_type r		 = m_rank_contains_abs_sample.rank(idx / t_sample_dens); //
		size_type result = r * t_sample_dens;
		size_type i		 = m_abs_samples[r];
		while (++result <= m_ones) {
			if ((result % t_sample_dens) == 0) {
				i = m_abs_samples[result / t_sample_dens];
			} else {
				i = i + m_differences[result - result / t_sample_dens - 1];
			}
			if (i >= idx) return result - 1;
		}
		return result - 1;
	};