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

  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.
 */

#ifndef __SYSTEMC_EXT_UTIL_SC_VECTOR_HH__
#define __SYSTEMC_EXT_UTIL_SC_VECTOR_HH__

#include <stdint.h>

#include <cstddef>
#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 : 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 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]

    using difference_type = std::ptrdiff_t;
    using value_type = typename AccessPolicy::Type;
    using reference = typename AccessPolicy::Type &;
    using pointer = typename AccessPolicy::Type *;
    using iterator_category = std::random_access_iterator_tag;

    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__
