/*****************************************************************************

  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
  more contributor license agreements.  See the NOTICE file distributed
  with this work for additional information regarding copyright ownership.
  Accellera 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.

 *****************************************************************************/

/*
 * Copyright 2018 Google, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#ifndef __SYSTEMC_EXT_UTIL_SC_VECTOR_HH__
#define __SYSTEMC_EXT_UTIL_SC_VECTOR_HH__

#include <stdint.h>

#include <exception>
#include <iterator>
#include <vector>

#include "../core/sc_module.hh"
#include "../core/sc_object.hh"
#include "messages.hh"

namespace sc_gem5
{

// Goop for supporting sc_vector_iter, simplified from the Accellera version.

#if __cplusplus >= 201103L

using std::enable_if;
using std::remove_const;
using std::is_same;
using std::is_const;

#else

template<bool Cond, typename T=void>
struct enable_if
{};

template<typename T>
struct enable_if<true, T>
{
    typedef T type;
};

template <typename T>
struct remove_const
{
    typedef T type;
};
template <typename T>
struct remove_const<const T>
{
    typedef T type;
};

template <typename T, typename U>
struct is_same
{
    static const bool value = false;
};
template <typename T>
struct is_same<T, T>
{
    static const bool value = true;
};

template <typename T>
struct is_const
{
    static const bool value = false;
};
template <typename T>
struct is_const<const T>
{
    static const bool value = true;
};

#endif

template <typename CT, typename T>
struct is_more_const
{
    static const bool value =
        is_same<typename remove_const<CT>::type,
                typename remove_const<T>::type>::value &&
        is_const<CT>::value >= is_const<T>::value;
};

struct special_result
{};

template <typename T>
struct remove_special_fptr
{};

template <typename T>
struct remove_special_fptr<special_result & (*)(T)>
{
    typedef T type;
};

#define SC_RPTYPE_(Type) \
    ::sc_gem5::remove_special_fptr< \
        ::sc_gem5::special_result & (*) Type>::type::value

#define SC_ENABLE_IF_(Cond) \
    typename ::sc_gem5::enable_if<SC_RPTYPE_(Cond)>::type * = NULL

} // namespace sc_gem5

namespace sc_core
{

template <typename T, typename MT>
class sc_vector_assembly;

template <typename T>
class sc_vector;

template <typename T, typename MT>
sc_vector_assembly<T, MT> sc_assemble_vector(
        sc_vector<T> &, MT(T::* member_ptr));

class sc_vector_base : public sc_object
{
  public:
    typedef size_t size_type;

    sc_vector_base(const char *_name) : sc_object(_name) {}

    virtual const char *kind() const { return "sc_vector"; }
    size_type size() const;
    const std::vector<sc_object *> &get_elements() const;

  protected:
    std::vector<void *> objs;

    // What's returned by get_elements, which really returns the elemenets
    // which are also objects.
    mutable std::vector<sc_object *> elements;

    sc_object *implicitCast(sc_object *p) const { return p; }
    sc_object *implicitCast(...) const
    {
        SC_REPORT_ERROR(SC_ID_VECTOR_NONOBJECT_ELEMENTS_, name());
        return nullptr;
    }
    virtual sc_object *objectCast(void *) const = 0;

    void checkIndex(size_type index) const;
    void forceParent() const;
    void unforceParent() const;

    void reportEmpty(const char *kind_, bool empty_dest) const;
};


/*
 * Non-standard iterator access adapters. Without using these, the classes as
 * defined in the standard won't compile because of redundant bind() overloads.
 */

template <typename Element>
class sc_direct_access
{
  public:
    typedef Element ElementType;
    typedef ElementType Type;
    typedef typename sc_gem5::remove_const<ElementType>::type PlainType;

    typedef sc_direct_access<ElementType> Policy;
    typedef sc_direct_access<PlainType> NonConstPolicy;
    typedef sc_direct_access<const PlainType> ConstPolicy;

    sc_direct_access() {}
    sc_direct_access(const NonConstPolicy &) {}

    template <typename U>
    sc_direct_access(const U &,
        SC_ENABLE_IF_((
            sc_gem5::is_more_const<
                    ElementType, typename U::Policy::ElementType>
        ))
    )
    {}

    ElementType *
    get(ElementType *this_) const
    {
        return this_;
    }
};

template <typename Element, typename Access>
class sc_member_access
{
  public:
    template <typename, typename>
    friend class sc_member_access;

    typedef Element ElementType;
    typedef Access AccessType;
    typedef AccessType (ElementType::*MemberType);
    typedef AccessType Type;
    typedef typename sc_gem5::remove_const<AccessType>::type PlainType;
    typedef typename sc_gem5::remove_const<ElementType>::type PlainElemType;

    typedef sc_member_access<ElementType, AccessType> Policy;
    typedef sc_member_access<PlainElemType, PlainType> NonConstPolicy;
    typedef sc_member_access<const PlainElemType, const PlainType> ConstPolicy;

    sc_member_access(MemberType ptr) : ptr_(ptr) {}
    sc_member_access(const NonConstPolicy &other) : ptr_(other.ptr_) {}

    AccessType *get(ElementType *this_) const { return &(this_->*ptr_); }

  private:
    MemberType ptr_;
};

template <typename Element,
          typename AccessPolicy=sc_direct_access<Element> >
class sc_vector_iter :
        public std::iterator<std::random_access_iterator_tag,
                             typename AccessPolicy::Type>,
        private AccessPolicy
{
  private:
    typedef Element ElementType;
    typedef typename AccessPolicy::Policy Policy;
    typedef typename AccessPolicy::NonConstPolicy NonConstPolicy;
    typedef typename AccessPolicy::ConstPolicy ConstPolicy;
    typedef typename Policy::Type AccessType;

    typedef typename sc_gem5::remove_const<ElementType>::type PlainType;
    typedef const PlainType ConstPlainType;
    typedef typename sc_direct_access<PlainType>::ConstPolicy
        ConstDirectPolicy;

    friend class sc_vector<PlainType>;
    template <typename, typename>
    friend class sc_vector_assembly;
    template <typename, typename>
    friend class sc_vector_iter;

    typedef std::iterator<std::random_access_iterator_tag, AccessType>
        BaseType;
    typedef sc_vector_iter ThisType;
    typedef sc_vector<PlainType> VectorType;
    typedef std::vector<void *> StorageType;

    template <typename U>
    struct SelectIter
    {
        typedef typename std::vector<void *>::iterator type;
    };
    template <typename U>
    struct SelectIter<const U>
    {
        typedef typename std::vector<void *>::const_iterator type;
    };
    typedef typename SelectIter<ElementType>::type RawIterator;
    typedef sc_vector_iter<ConstPlainType, ConstPolicy> ConstIterator;
    typedef sc_vector_iter<ConstPlainType, ConstDirectPolicy>
        ConstDirectIterator;

    RawIterator it_;

    sc_vector_iter(RawIterator it, Policy acc=Policy()) :
        Policy(acc), it_(it)
    {}

    Policy const &get_policy() const { return *this; }

  public:
    // Conforms to Random Access Iterator category.
    // See ISO/IEC 14882:2003(E), 24.1 [lib.iterator.requirements]

    typedef typename BaseType::difference_type difference_type;
    typedef typename BaseType::reference reference;
    typedef typename BaseType::pointer pointer;

    sc_vector_iter() : Policy(), it_() {}

    template <typename It>
    sc_vector_iter(const It &it,
        SC_ENABLE_IF_((
            sc_gem5::is_more_const<
                ElementType, typename It::Policy::ElementType>
        ))
    ) : Policy(it.get_policy()), it_(it.it_)
    {}

    ThisType &
    operator ++ ()
    {
        ++it_;
        return *this;
    }
    ThisType &
    operator -- ()
    {
        --it_;
        return *this;
    }
    ThisType
    operator ++ (int)
    {
        ThisType old(*this);
        ++it_;
        return old;
    }
    ThisType
    operator -- (int)
    {
        ThisType old(*this);
        --it_;
        return old;
    }

    ThisType
    operator + (difference_type n) const
    {
        return ThisType(it_ + n, get_policy());
    }
    ThisType
    operator - (difference_type n) const
    {
        return ThisType(it_ - n, get_policy());
    }

    ThisType &
    operator += (difference_type n)
    {
        it_ += n;
        return *this;
    }

    ThisType &
    operator -= (difference_type n)
    {
        it_ -= n;
        return *this;
    }

    bool
    operator == (const ConstDirectIterator &other) const
    {
        return it_ == other.it_;
    }
    bool
    operator != (const ConstDirectIterator &other) const
    {
        return it_ != other.it_;
    }
    bool
    operator <= (const ConstDirectIterator &other) const
    {
        return it_ <= other.it_;
    }
    bool
    operator >= (const ConstDirectIterator &other) const
    {
        return it_ >= other.it_;
    }
    bool
    operator < (const ConstDirectIterator &other) const
    {
        return it_ < other.it_;
    }
    bool
    operator > (const ConstDirectIterator &other) const
    {
        return it_ > other.it_;
    }

    reference
    operator * () const
    {
        return *Policy::get(static_cast<ElementType *>((void *)*it_));
    }
    pointer
    operator -> () const
    {
        return Policy::get(static_cast<ElementType *>((void *)*it_));
    }
    reference
    operator [] (difference_type n) const
    {
        return *Policy::get(static_cast<ElementType *>((void *)it_[n]));
    }

    difference_type
    operator - (ConstDirectIterator const &other) const
    {
        return it_ - other.it_;
    }
};

template <typename T>
class sc_vector : public sc_vector_base
{
  public:
    using sc_vector_base::size_type;
    typedef sc_vector_iter<T> iterator;
    typedef sc_vector_iter<const T> const_iterator;

    sc_vector() : sc_vector_base(::sc_core::sc_gen_unique_name("vector")) {}
    explicit sc_vector(const char *_name) : sc_vector_base(_name) {}
    sc_vector(const char *_name, size_type _size) : sc_vector_base(_name)
    {
        init(_size);
    }
    template <typename Creator>
    sc_vector(const char *_name, size_type _size, Creator creator) :
        sc_vector_base(_name)
    {
        init(_size, creator);
    }
    virtual ~sc_vector() { clear(); }

    void
    init(size_type _size)
    {
        init(_size, &sc_vector<T>::create_element);
    }
    static T *
    create_element(const char *_name, size_type index)
    {
        return new T(_name);
    }

    template <typename Creator>
    void
    init(size_type _size, Creator creator)
    {
        forceParent();
        try {
            for (size_type i = 0; i < _size; i++) {
                // XXX The name and scope of these objects needs to be handled
                // specially.
                T *p = creator(sc_gen_unique_name(basename()), i);
                objs.push_back(p);
            }
        } catch (...) {
            unforceParent();
            clear();
            throw;
        }
        unforceParent();
    }

    T &operator [] (size_type index) { return *static_cast<T *>(objs[index]); }
    const T &
    operator [] (size_type index) const
    {
        return *static_cast<const T *>(objs[index]);
    }

    T &
    at(size_type index)
    {
        this->checkIndex(index);
        return *static_cast<T *>(objs[index]);
    }
    const T &
    at(size_type index) const
    {
        this->checkIndex(index);
        return *static_cast<const T *>(objs[index]);
    }

    iterator begin() { return objs.begin(); }
    iterator end() { return objs.end(); }
    const_iterator begin() const { return objs.begin(); }
    const_iterator end() const { return objs.end(); }
    const_iterator cbegin() const { return objs.begin(); }
    const_iterator cend() const { return objs.end(); }

    template <typename ContainerType, typename ArgumentType>
    iterator
    bind(sc_vector_assembly<ContainerType, ArgumentType> c)
    {
        return bind(c.begin(), c.end());
    }

    template <typename BindableContainer>
    iterator
    bind(BindableContainer &c)
    {
        return bind(c.begin(), c.end());
    }

    template <typename BindableIterator>
    iterator
    bind(BindableIterator first, BindableIterator last)
    {
        return bind(first, last, this->begin());
    }

    template <typename BindableIterator>
    iterator
    bind(BindableIterator first, BindableIterator last, iterator from)
    {
        if (!size() || from == end() || first == last)
            reportEmpty(kind(), from == end());

        while (from != end() && first != last)
            (*from++).bind(*first++);
        return from;
    }

    template <typename ContainerType, typename ArgumentType>
    iterator
    operator () (sc_vector_assembly<ContainerType, ArgumentType> c)
    {
        return (*this)(c.begin(), c.end());
    }

    template <typename ArgumentContainer>
    iterator
    operator () (ArgumentContainer &c)
    {
        return (*this)(c.begin(), c.end());
    }

    template <typename ArgumentIterator>
    iterator
    operator () (ArgumentIterator first, ArgumentIterator last)
    {
        return (*this)(first, last, this->begin());
    }

    template <typename ArgumentIterator>
    iterator
    operator () (ArgumentIterator first, ArgumentIterator last, iterator from)
    {
        if (!size() || from == end() || first == last)
            reportEmpty(kind(), from == end());

        while (from != end() && first != last)
            (*from++)(*first++);
        return from;
    }

  private:
    // Disabled
    sc_vector(const sc_vector &);
    sc_vector &operator = (const sc_vector &);

    void
    clear()
    {
        for (auto obj: objs)
            delete static_cast<T *>(obj);
    }

    template <typename, typename>
    friend class sc_vector_assembly;

    sc_object *
    objectCast(void *ptr) const
    {
        return implicitCast(static_cast<T *>(ptr));
    }
};

template <typename T, typename MT>
class sc_vector_assembly
{
  public:
    friend sc_vector_assembly<T, MT> sc_assemble_vector<>(
            sc_vector<T> &, MT (T::*));

    typedef size_t size_type;
    typedef sc_vector_iter<T, sc_member_access<T, MT> > iterator;
    typedef sc_vector_iter<
        const T, sc_member_access<const T, const MT> > const_iterator;
    typedef MT (T::*MemberType);

    sc_vector_assembly(const sc_vector_assembly &other) :
        vec_(other.vec_), ptr_(other.ptr_)
    {}

    iterator begin() { return iterator(vec_->begin().it_, ptr_); }
    iterator end() { return iterator(vec_->end().it_, ptr_); }

    const_iterator
    cbegin() const
    {
        return const_iterator(vec_->begin().it_, ptr_);
    }
    const_iterator
    cend() const
    {
        return const_iterator(vec_->end().it_, ptr_);
    }

    const_iterator
    begin() const
    {
        return const_iterator(vec_->begin().it_, ptr_);
    }
    const_iterator
    end() const
    {
        return const_iterator(vec_->end().it_, ptr_);
    }

    size_type size() const { return vec_->size(); }

    std::vector<sc_object *>
    get_elements() const
    {
        std::vector<sc_object *> ret;
        for (const_iterator it = begin(); it != end(); it++) {
            sc_object *obj_ptr = vec_->objectCast(const_cast<MT *>(&*it));

            if (obj_ptr)
                ret.push_back(obj_ptr);
        }
        return ret;
    }

    typename iterator::reference
    operator [] (size_type i)
    {
        return (*vec_)[i].*ptr_;
    }
    typename const_iterator::reference
    operator [] (size_type i) const
    {
        return (*vec_)[i].*ptr_;
    }

    typename iterator::reference
    at(size_type i)
    {
        return vec_->at(i).*ptr_;
    }
    typename const_iterator::reference
    at(size_type i) const
    {
        return vec_->at(i).*ptr_;
    }

    template <typename ContainerType, typename ArgumentType>
    iterator
    bind(sc_vector_assembly<ContainerType, ArgumentType> c)
    {
        return bind(c.begin(), c.end());
    }

    template <typename BindableContainer>
    iterator
    bind(BindableContainer &c)
    {
        return bind(c.begin(), c.end());
    }

    template <typename BindableIterator>
    iterator
    bind(BindableIterator first, BindableIterator last)
    {
        return bind(first, last, this->begin());
    }

    template <typename BindableIterator>
    iterator
    bind(BindableIterator first, BindableIterator last, iterator from)
    {
        if (!size() || from == end() || first == last)
            vec_->reportEmpty("sc_vector_assembly", from == end());

        while (from != end() && first != last)
            (*from++).bind(*first++);
        return from;
    }

    template <typename BindableIterator>
    iterator
    bind(BindableIterator first, BindableIterator last,
            typename sc_vector<T>::iterator from)
    {
        return bind(first, last, iterator(from.it_, ptr_));
    }

    template <typename ContainerType, typename ArgumentType>
    iterator
    operator () (sc_vector_assembly<ContainerType, ArgumentType> c)
    {
        return (*this)(c.begin(), c.end());
    }

    template <typename ArgumentContainer>
    iterator
    operator () (ArgumentContainer &c)
    {
        return (*this)(c.begin(), c.end());
    }

    template <typename ArgumentIterator>
    iterator
    operator () (ArgumentIterator first, ArgumentIterator last)
    {
        return (*this)(first, last, this->begin());
    }

    template <typename ArgumentIterator>
    iterator
    operator () (ArgumentIterator first, ArgumentIterator last, iterator from)
    {
        if (!size() || from == end() || first == last)
            vec_->reportEmpty("sc_vector_assembly", from == end());

        while (from != end() && first != last)
            (*from++)(*first++);
        return from;
    }

    template <typename ArgumentIterator>
    iterator
    operator () (ArgumentIterator first, ArgumentIterator last,
                 typename sc_vector<T>::iterator from)
    {
        return (*this)(first, last, iterator(from.it_, ptr_));
    }

  private:
    sc_vector_assembly(sc_vector<T> &v, MemberType ptr) :
        vec_(&v), ptr_(ptr)
    {}

    sc_vector<T> *vec_;
    MemberType ptr_;
};

template <typename T, typename MT>
sc_vector_assembly<T, MT>
sc_assemble_vector(sc_vector<T> &v, MT (T::*ptr))
{
    return sc_vector_assembly<T, MT>(v, ptr);
}

} // namespace sc_core

#endif  //__SYSTEMC_EXT_UTIL_SC_VECTOR_HH__
