/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

#ifndef ARRAY_OF_DOUBLES_INTERSECTION_HPP_
#define ARRAY_OF_DOUBLES_INTERSECTION_HPP_

#include <vector>
#include <memory>

#include "array_of_doubles_sketch.hpp"
#include "tuple_intersection.hpp"

namespace datasketches {

template<
  typename Policy,
  typename Allocator = std::allocator<double>
>
class array_of_doubles_intersection: public tuple_intersection<aod<Allocator>, Policy, AllocAOD<Allocator>> {
public:
  using Summary = aod<Allocator>;
  using AllocSummary = AllocAOD<Allocator>;
  using Base = tuple_intersection<Summary, Policy, AllocSummary>;
  using CompactSketch = compact_array_of_doubles_sketch_alloc<Allocator>;
  using resize_factor = theta_constants::resize_factor;

  explicit array_of_doubles_intersection(uint64_t seed = DEFAULT_SEED, const Policy& policy = Policy(), const Allocator& allocator = Allocator());

  CompactSketch get_result(bool ordered = true) const;
};

} /* namespace datasketches */

#include "array_of_doubles_intersection_impl.hpp"

#endif
