// Copyright (c) 2011 CNRS and LIRIS' Establishments (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
//
// $URL: https://github.com/CGAL/cgal/blob/v6.1/Linear_cell_complex/include/CGAL/Linear_cell_complex_for_generalized_map.h $
// $Id: include/CGAL/Linear_cell_complex_for_generalized_map.h b26b07a1242 $
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s)     : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
//
#ifndef CGAL_LINEAR_CELL_COMPLEX_FOR_GENERALIZED_MAP_H
#define CGAL_LINEAR_CELL_COMPLEX_FOR_GENERALIZED_MAP_H 1

#include <CGAL/Linear_cell_complex_fwd.h>
#include <CGAL/Linear_cell_complex_base.h>
#include <CGAL/Linear_cell_complex_traits.h>
#include <CGAL/Linear_cell_complex_min_items.h>
#include <CGAL/Generalized_map.h>
#include <CGAL/GMap_linear_cell_complex_storages.h>
#include <CGAL/GMap_linear_cell_complex_storages_with_index.h>

namespace CGAL {

  /** @file Linear_cell_complex_for_generalized_map.h
   * Definition of a linear cell complex based on generalized map, having
   * points associated to all vertices.
   */

  // Linear_cell_complex_for_generalized_map class_base.
  template < unsigned int d_, unsigned int ambient_dim,
             class Traits_, class Items_, class Alloc_,
             template<unsigned int,class,class,class,class> class CMap,
             class Refs_, class Storage_ >
    class Linear_cell_complex_for_generalized_map_base:
        public Linear_cell_complex_base<d_, ambient_dim, Traits_,
                                        Items_, Alloc_, CMap, Refs_, Storage_>
    {
    public:
      typedef Linear_cell_complex_for_generalized_map_base<d_, ambient_dim,
                          Traits_, Items_, Alloc_, CMap, Refs_, Storage_>  Self;

      typedef Linear_cell_complex_base<d_, ambient_dim,
                          Traits_, Items_, Alloc_, CMap, Refs_, Storage_> Base;

      typedef Traits_ Traits;
      typedef Items_  Items;
      typedef Alloc_  Alloc;
      typedef Refs_   Refs;

      static const unsigned int ambient_dimension = Base::ambient_dimension;
      static const unsigned int dimension = Base::dimension;

      typedef typename Base::Dart_descriptor       Dart_descriptor;
      typedef typename Base::Dart_const_descriptor Dart_const_descriptor;
      typedef typename Base::Helper            Helper;

      typedef typename Base::Point  Point;
      typedef typename Base::Vector Vector;
      typedef typename Base::FT     FT;

      typedef typename Base::Dart_range Dart_range;

      typedef typename Base::template Attribute_type<0>::type Vertex_attribute;
      typedef typename Base::template Attribute_descriptor<0>::type
      Vertex_attribute_descriptor;
      typedef typename Base::template Attribute_const_descriptor<0>::type
      Vertex_attribute_const_descriptor;

      typedef typename Base::template Attribute_range<0>::type
      Vertex_attribute_range;
      typedef typename Base::template Attribute_const_range<0>::type
      Vertex_attribute_const_range;

      typedef typename Base::size_type size_type;

      typedef typename Base::Use_index Use_index;
      typedef typename Base::Storage Storage;
      typedef typename Base::Exception_no_more_available_mark
      Exception_no_more_available_mark;

      Linear_cell_complex_for_generalized_map_base() : Base()
      {}

      /** Copy the given linear cell complex into *this.
       *  Note that both LCC can have different dimensions and/or non void attributes.
       *  @param alcc the linear cell complex to copy.
       *  @post *this is valid.
       */
      Linear_cell_complex_for_generalized_map_base(const Self & alcc) : Base(alcc)
      {}

      Linear_cell_complex_for_generalized_map_base(Self && alcc) : Base(alcc)
      {}

      template <unsigned int d2,  unsigned int ambient_dim2, class Traits2,
                class Items2, class Alloc2,
                template<unsigned int,class,class,class,class> class CMap2,
                class Ref2, class Storage2>
      Linear_cell_complex_for_generalized_map_base
      (const Linear_cell_complex_for_generalized_map_base<d2, ambient_dim2,
       Traits2, Items2, Alloc2, CMap2, Ref2, Storage2>& alcc) : Base(alcc)
      {}

      template <unsigned int d2,  unsigned int ambient_dim2, class Traits2,
                class Items2, class Alloc2,
                template<unsigned int,class,class,class,class> class CMap2,
                class Ref2, class Storage2, typename Converters>
      Linear_cell_complex_for_generalized_map_base
      (const Linear_cell_complex_for_generalized_map_base<d2, ambient_dim2,
       Traits2, Items2, Alloc2, CMap2, Ref2, Storage2>& alcc,
       const Converters& converters) : Base(alcc, converters)
      {}

      template <unsigned int d2,  unsigned int ambient_dim2, class Traits2,
                class Items2, class Alloc2,
                template<unsigned int,class,class,class,class> class CMap2,
                class Ref2, class Storage2, typename Converters, typename DartInfoConverter>
      Linear_cell_complex_for_generalized_map_base
      (const Linear_cell_complex_for_generalized_map_base<d2, ambient_dim2,
       Traits2, Items2, Alloc2, CMap2, Ref2, Storage2>& alcc,
       const Converters& converters,
       const DartInfoConverter& dartinfoconverter) :
        Base(alcc, converters, dartinfoconverter)
      {}

      template <unsigned int d2,  unsigned int ambient_dim2, class Traits2,
                class Items2, class Alloc2,
                template<unsigned int,class,class,class,class> class CMap2,
                class Ref2, class Storage2, typename Converters, typename DartInfoConverter,
                typename PointConverter>
      Linear_cell_complex_for_generalized_map_base
      (const Linear_cell_complex_for_generalized_map_base<d2, ambient_dim2,
       Traits2, Items2, Alloc2, CMap2, Ref2, Storage2>& alcc,
       const Converters& converters,
       const DartInfoConverter& dartinfoconverter,
       const PointConverter& pointconverter) :
        Base(alcc, converters, dartinfoconverter, pointconverter)
      {}

      Self & operator= (const Self & alcc)
      {
        Base::operator=(alcc);
        return *this;
      }

      friend std::ostream& operator<< (std::ostream& os, const Self& amap)
      {
        save_generalized_map(amap, os);
        return os;
      }

      friend std::ifstream& operator>> (std::ifstream& is, Self& amap)
      {
        load_generalized_map(is, amap);
        return is;
      }
    };

  template < unsigned int d_, unsigned int ambient_dim,
             class Traits_, class Items_, class Alloc_,
             template<unsigned int,class,class,class,class> class CMap,
             class Storage_ >
    class Linear_cell_complex_for_generalized_map:
        public Linear_cell_complex_for_generalized_map_base
        <d_, ambient_dim, Traits_, Items_, Alloc_, CMap,
        Linear_cell_complex_for_generalized_map<d_, ambient_dim, Traits_,
        Items_, Alloc_, CMap, Storage_>, Storage_>
    {
    public:
     typedef Linear_cell_complex_for_generalized_map<d_, ambient_dim,
                          Traits_, Items_, Alloc_, CMap, Storage_>  Self;

      typedef Linear_cell_complex_for_generalized_map_base<d_, ambient_dim,
                          Traits_, Items_, Alloc_, CMap, Self, Storage_> Base;

      typedef Traits_ Traits;
      typedef Items_  Items;
      typedef Alloc_  Alloc;

      Linear_cell_complex_for_generalized_map() : Base()
      {}

      /** Copy the given linear cell complex into *this.
       *  Note that both LCC can have different dimensions and/or non void attributes.
       *  @param alcc the linear cell complex to copy.
       *  @post *this is valid.
       */
      Linear_cell_complex_for_generalized_map(const Self& alcc) : Base(alcc)
      {}

      Linear_cell_complex_for_generalized_map(Self&& alcc) : Base(alcc)
      {}

      template <unsigned int d2,  unsigned int ambient_dim2, class Traits2,
                class Items2, class Alloc2,
                template<unsigned int,class,class,class,class> class CMap2,
                class Storage2>
      Linear_cell_complex_for_generalized_map
      (const Linear_cell_complex_for_generalized_map<d2, ambient_dim2,
       Traits2, Items2, Alloc2, CMap2, Storage2>& alcc) : Base(alcc)
      {}

      template <unsigned int d2,  unsigned int ambient_dim2, class Traits2,
                class Items2, class Alloc2,
                template<unsigned int,class,class,class,class> class CMap2,
                class Storage2, typename Converters>
      Linear_cell_complex_for_generalized_map
      (const Linear_cell_complex_for_generalized_map<d2, ambient_dim2,
       Traits2, Items2, Alloc2, CMap2, Storage2>& alcc,
       const Converters& converters) : Base(alcc, converters)
      {}

      template <unsigned int d2,  unsigned int ambient_dim2, class Traits2,
                class Items2, class Alloc2,
                template<unsigned int,class,class,class,class> class CMap2,
                class Storage2, typename Converters, typename DartInfoConverter>
      Linear_cell_complex_for_generalized_map
      (const Linear_cell_complex_for_generalized_map<d2, ambient_dim2,
       Traits2, Items2, Alloc2, CMap2, Storage2>& alcc,
       const Converters& converters,
       const DartInfoConverter& dartinfoconverter) :
        Base(alcc, converters, dartinfoconverter)
      {}

      template <unsigned int d2,  unsigned int ambient_dim2, class Traits2,
                class Items2, class Alloc2,
                template<unsigned int,class,class,class,class> class CMap2,
                class Storage2, typename Converters,
                typename DartInfoConverter, typename PointConverter>
      Linear_cell_complex_for_generalized_map
      (const Linear_cell_complex_for_generalized_map<d2, ambient_dim2,
       Traits2, Items2, Alloc2, CMap2, Storage2>& alcc,
       const Converters& converters, const DartInfoConverter& dartinfoconverter,
       const PointConverter& pointconverter) :
        Base(alcc, converters, dartinfoconverter, pointconverter)
      {}

      Self & operator= (const Self & alcc)
      {
        Base::operator=(alcc);
        return *this;
      }

      void clear() { Base::clear(); } //need explicit definition for Has_member_clear in bgl helpers
};

} // namespace CGAL

#endif // CGAL_LINEAR_CELL_COMPLEX_FOR_GENERALIZED_MAP_H //
// EOF //

