/************************************************************************
*
* 23.containers.h - definitions of helpers used in clause 23 tests
*
* $Id: 23.containers.h
*
***************************************************************************
*
* 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 RW_23_CONTAINERS_H_INCLUDED
#define RW_23_CONTAINERS_H_INCLUDED

#include <testdefs.h>
#include <rw_value.h>       // for UserClass, UserPOD
#include <rw_char.h>        // for rw_expand ()
#include <driver.h>         // for rw_assert ()

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

// defines enumerations identifying the general template arguments,
// sets of overloaded functions, member types used in the declarations
// of their signatures, and specific overloads of such member functions
struct ContainerIds {

    // identifiers for the T template argument
    enum ElemId { UserPOD, UserClass };

    // identifiers for the Allocator template argument
    enum AllocId { DefaultAlloc, UserAlloc };

    // identifiers for the Iterator template argument
    // used with member templates
    enum IteratorId {
        None,
        Input, Forward, Bidir, Random,
        Pointer, ConstPointer,
        Iterator, ConstIterator,
        ReverseIterator, ConstReverseIterator
    };

    enum ContainerId {
        List, Vector, Deque, Queue, Stack
    };

    // identifies a set of overloaded member or non-member
    // container functions
    enum FuncId {
        // 6 bits, 64 functions max
        // common
        /*  0 */ fid_ctor,
        /*  1 */ fid_op_set,
        /*  2 */ fid_assign,
        /*  3 */ fid_get_allocator,
        /*  4 */ fid_begin,
        /*    */ fid_begin_const = fid_begin,
        /*  5 */ fid_end,
        /*    */ fid_end_const = fid_end,
        /*  6 */ fid_rbegin,
        /*    */ fid_rbegin_const = fid_rbegin,
        /*  7 */ fid_rend,
        /*    */ fid_rend_const = fid_rend,
        /*  8 */ fid_empty,
        /*  9 */ fid_size,
        /* 10 */ fid_max_size,
        /* 11 */ fid_resize,
        /* 12 */ fid_insert,
        /* 13 */ fid_erase,
        /* 14 */ fid_swap,
        /* 15 */ fid_clear,
        /* 16 */ fid_op_equal,
        /* 17 */ fid_op_less,
        /* 18 */ fid_op_not_equal,
        /* 19 */ fid_op_greater,
        /* 20 */ fid_op_greater_equal,
        /* 21 */ fid_op_less_equal,
        /* 22 */ fid_push_back,

        // list, deque, vector
        /* 23 */ fid_front,
        /*    */ fid_front_const = fid_front,
        /* 24 */ fid_back,
        /*    */ fid_back_const = fid_back,
        /* 25 */ fid_pop_back,

        // list, deque
        /* 26 */ fid_push_front,
        /* 27 */ fid_pop_front,

        // list
        /* 28 */ fid_splice,
        /* 29 */ fid_remove,
        /* 30 */ fid_remove_if,
        /* 31 */ fid_unique,
        /* 32 */ fid_merge,
        /* 33 */ fid_sort,
        /* 34 */ fid_reverse,

        // vector, string, deque
        /* 35 */ fid_op_index,
        /*    */ fid_op_index_const = fid_op_index,
        /* 36 */ fid_at,
        /*    */ fid_at_const = fid_at,

        // vector, string
        /* 37 */ fid_capacity,
        /* 38 */ fid_reserve,

        // vector<bool>
        /* 39 */ fid_flip,

        /* -- */ fid_bits = 6,
        /* -- */ fid_mask = 63
    };

    // identifies the type of a function argument, including
    // the implicit this
    enum ArgId {
        // 4 bits, 16 types max
        /*  0 */ arg_void,    // void
        /*  1 */ arg_size,    // size_type
        /*  2 */ arg_val,     // value_type
        /*  3 */ arg_ref,     // reference
        /*  4 */ arg_cref,    // const_reference
        /*  5 */ arg_iter,    // iterator
        /*  6 */ arg_citer,   // const_iterator
        /*  7 */ arg_range,   // Iterator, Iterator
        /*  8 */ arg_cont,    // container& (or this for member functions)
        /*  9 */ arg_ccont,   // const container& (or const this for members)
        /* 10 */ arg_alloc,   // const allocator&
        /* 11 */ arg_pred,    // Predicate
        /* 12 */ arg_bpred,   // BinaryPredicate
        /* 13 */ arg_comp,    // Compare
        /* -- */ arg_bits = 4,
        /* -- */ arg_mask = 15
    };

    enum {
        // bit designating a member function
        bit_member = 1 << (fid_bits + 6 * arg_bits)
    };

    static ArgId arg_type (_RWSTD_SIZE_T id, int argno) {
        return ArgId (((id >> fid_bits) >> argno * arg_bits) & arg_mask);
    }
};

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

struct ContainerFunc
{
    ContainerIds::ElemId      elem_id_;
    ContainerIds::AllocId     alloc_id_;
    ContainerIds::IteratorId  iter_id_;
    ContainerIds::ContainerId cont_id_;
    _RWSTD_SIZE_T             which_;
};


// describes a single test case for any overload of any container
// function (the same test case can be used to exercise more
// than one overload of the same function)
struct ContainerTestCase
{
    int            line;      // test case line number

    int            off;       // offset (position argument)
    int            size;      // size (count argument)

    int            off2;      // offset 2 (position argument)
    int            size2;     // size 2 (count argument)

    int            val;       // value (single character to append)

    const char*    str;       // controlled sequence
    _RWSTD_SIZE_T  str_len;   // length of sequence

    const char*    arg;       // sequence to insert
    _RWSTD_SIZE_T  arg_len;   // length of sequence

    const char*    res;       // resulting sequence
    _RWSTD_SIZE_T  nres;      // length of sequence or expected result value

    int            bthrow;    // exception expected
};


// describes a set of test cases for a single overload of a function
struct ContainerTest
{
    // container function overload to exercise
    _RWSTD_SIZE_T which;

    // test cases to exercise overload with
    const ContainerTestCase *cases;

    // number of test cases
    _RWSTD_SIZE_T case_count;
};


typedef void ContainerTestFunc (const ContainerFunc&, const ContainerTestCase&);

_TEST_EXPORT int
rw_run_cont_test (int, char**, const char*, const char*,
                  ContainerIds::ContainerId, ContainerTestFunc*,
                  const ContainerTest*, _RWSTD_SIZE_T);

typedef void VoidFunc ();

_TEST_EXPORT int
rw_run_cont_test (int, char**, const char*, const char*,
                  ContainerIds::ContainerId, VoidFunc* const*,
                  const ContainerTest*, _RWSTD_SIZE_T);

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

template <class T>
class ContainerTestCaseData
{
private:

    // not defined, not copyable, not assignable
    ContainerTestCaseData (const ContainerTestCaseData&);
    void operator= (const ContainerTestCaseData&);

    // for convenience
    typedef _RWSTD_SIZE_T SizeType;

public:

    SizeType strlen_;   // the length of the expanded string
    SizeType arglen_;   // the length of the expanded argument
    SizeType reslen_;   // the length of the expanded result

    // the offset and extent (the number of elements) of
    // the first range into the container object being modified
    SizeType off1_;
    SizeType ext1_;

    // the offset and extent (the number of elements) of
    // the argument of the function call
    SizeType off2_;
    SizeType ext2_;

    const T* str_;   // pointer to the expanded string
    const T* arg_;   // pointer to the expanded argument
    const T* res_;   // pointer to the expanded result

    const ContainerFunc     &func_;
    const ContainerTestCase &tcase_;

    // converts the narrow (and possibly) condensed strings to fully
    // expanded wide character arrays that can be used to construct
    // container objects
    ContainerTestCaseData (const ContainerFunc &func,
                           const ContainerTestCase &tcase)
        : func_ (func), tcase_ (tcase) {

        char buf [256];

        strlen_ = sizeof (buf);
        char* str = rw_expand (buf, tcase.str, tcase.str_len, &strlen_);
        str_ = T::from_char (str, strlen_);
        if (str != buf)
            delete[] str;

        arglen_ = sizeof (buf);
        str = rw_expand (buf, tcase.arg, tcase.arg_len, &arglen_);
        arg_ = T::from_char (str, arglen_);
        if (str != buf)
            delete[] str;

        reslen_ = sizeof (buf);
        str = rw_expand (buf, tcase.res, tcase.nres, &reslen_);
        res_ = T::from_char (str, reslen_);
        if (str != buf)
            delete[] str;

        // compute the offset and extent of the container object
        // representing the controlled sequence and the offset
        // and extent of the argument of the function call
        const SizeType argl = tcase_.arg ? arglen_ : strlen_;

        off1_ = SizeType (tcase_.off) < strlen_ ?
            SizeType (tcase_.off) : strlen_;

        ext1_ = off1_ + tcase_.size < strlen_ ?
            SizeType (tcase_.size) : strlen_ - off1_;

        off2_ = SizeType (tcase_.off2) < argl ?
            SizeType (tcase_.off2) : argl;

        ext2_ = off2_ + tcase_.size2 < argl ?
            SizeType (tcase_.size2) : argl - off2_;
    }

    ~ContainerTestCaseData () {
        // clean up dynamically allocated memory
        delete[] str_;
        delete[] arg_;
        delete[] res_;
    }
};

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

// base class-functor for the range template overloads testing
template <class Cont>
struct ContRangeBase {

    typedef typename Cont::value_type                 ContVal;
    typedef typename Cont::iterator                   ContIter;
    typedef typename Cont::const_iterator             ContConstIter;
    typedef typename Cont::reverse_iterator           ContRevIter;
    typedef typename Cont::const_reverse_iterator     ContConstRevIter;

    ContRangeBase () { }

    virtual ~ContRangeBase () { /* silence warnings */ }

    static ContIter
    begin (Cont &cont, ContIter*) {
        return cont.begin ();
    }

    static ContConstIter
    begin (const Cont &cont, ContConstIter*) {
        return cont.begin ();
    }

    static ContRevIter
    begin (Cont &cont, ContRevIter*) {
        return cont.rbegin ();
    }

    static ContConstRevIter
    begin (const Cont &cont, ContConstRevIter*) {
        return cont.rbegin ();
    }

    virtual Cont&
    operator() (Cont &cont, const ContainerTestCaseData<ContVal>&) const {
        RW_ASSERT (!"logic error: should be never called");
        return cont;
    }
};

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

#  define CONTAINER_TEST_DISPATCH(Alloc, fname, func, tcase)    \
    if (ContainerIds::UserPOD == func.elem_id_)                 \
        fname (UserPOD (), (Alloc<UserPOD>*)0, func, tcase);    \
    else                                                        \
        fname (UserClass (), (Alloc<UserClass>*)0, func, tcase)


#define DEFINE_CONTAINER_TEST_DISPATCH(fname)                             \
    static void                                                           \
    fname (const ContainerFunc     &func,                                 \
           const ContainerTestCase &tcase) {                              \
        if (ContainerIds::DefaultAlloc == func.alloc_id_) {               \
            CONTAINER_TEST_DISPATCH (std::allocator, fname, func, tcase); \
        }                                                                 \
        else if (ContainerIds::UserAlloc == func.alloc_id_) {             \
            CONTAINER_TEST_DISPATCH (UserAlloc, fname, func, tcase);      \
        }                                                                 \
        else                                                              \
            RW_ASSERT (!"logic error: bad allocator");                    \
    } typedef void rw_unused_typedef


#define CONTAINER_TFUNC(T, Allocator)         \
    void (*)(T*, Allocator<T>*,               \
             const ContainerTestCaseData<T>&)

#define CONTAINER_TFUNC_ADDR(fname, T, Allocator) \
    (VoidFunc*)(CONTAINER_TFUNC (T, Allocator))   \
        &fname<T, Allocator<T> >

#define DEFINE_CONTAINER_TEST_FUNCTIONS(fname)                 \
    static VoidFunc* const fname ## _func_array [] = {         \
      CONTAINER_TFUNC_ADDR (fname, UserPOD, std::allocator),   \
      CONTAINER_TFUNC_ADDR (fname, UserPOD, UserAlloc),        \
                                                               \
      CONTAINER_TFUNC_ADDR (fname, UserClass, std::allocator), \
      CONTAINER_TFUNC_ADDR (fname, UserClass, UserAlloc)       \
    }

#endif   // RW_23_CONTAINERS_H_INCLUDED
