/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed 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 (c) 2001, 2002, 2003 Eliot Dresselhaus

  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
  "Software"), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to
  the following conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef included_clib_vec_bootstrap_h
#define included_clib_vec_bootstrap_h

/** \file
    Vector bootstrap header file
*/

/* Bootstrap include so that #include <vppinfra/mem.h> can include e.g.
   <vppinfra/mheap.h> which depends on <vppinfra/vec.h>. */

/** \brief vector header structure

   Bookkeeping header preceding vector elements in memory.
   User header information may preceed standard vec header.
   If you change u32 len -> u64 len, single vectors can
   exceed 2**32 elements. Clib heaps are vectors. */

typedef struct
{
  u32 len; /**< Number of elements in vector (NOT its allocated length). */
  u8 hdr_size;	      /**< header size divided by VEC_MIN_ALIGN */
  u8 log2_align : 7;  /**< data alignment */
  u8 default_heap : 1; /**< vector uses default heap */
  u8 grow_elts;	       /**< number of elts vector can grow without realloc */
  u8 vpad[1];	       /**< pad to 8 bytes */
  u8 vector_data[0];  /**< Vector data . */
} vec_header_t;

#define VEC_MIN_ALIGN 8

/** \brief Find the vector header

    Given the user's pointer to a vector, find the corresponding
    vector header

    @param v pointer to a vector
    @return pointer to the vector's vector_header_t
*/
#define _vec_find(v)	((vec_header_t *) (v) - 1)
#define _vec_heap(v)	(((void **) (_vec_find (v)))[-1])

always_inline uword __vec_align (uword data_align, uword configuered_align);
always_inline uword __vec_elt_sz (uword elt_sz, int is_void);

#define _vec_round_size(s) \
  (((s) + sizeof (uword) - 1) &~ (sizeof (uword) - 1))
#define _vec_is_void(P)                                                       \
  __builtin_types_compatible_p (__typeof__ ((P)[0]), void)
#define _vec_elt_sz(V)	 __vec_elt_sz (sizeof ((V)[0]), _vec_is_void (V))
#define _vec_align(V, A) __vec_align (__alignof__((V)[0]), A)

always_inline __clib_nosanitize_addr uword
vec_get_header_size (void *v)
{
  uword header_size = _vec_find (v)->hdr_size * VEC_MIN_ALIGN;
  return header_size;
}

/** \brief Find a user vector header

    Finds the user header of a vector with unspecified alignment given
    the user pointer to the vector.
*/

always_inline void *
vec_header (void *v)
{
  return v ? v - vec_get_header_size (v) : 0;
}

/** \brief Find the end of user vector header

    Finds the end of the user header of a vector with unspecified
    alignment given the user pointer to the vector.
*/

always_inline void *
vec_header_end (void *v)
{
  return v + vec_get_header_size (v);
}

/** \brief Number of elements in vector (rvalue-only, NULL tolerant)

    vec_len (v) checks for NULL, but cannot be used as an lvalue.
    If in doubt, use vec_len...
*/

static_always_inline u32
__vec_len (void *v)
{
  return _vec_find (v)->len;
}

#define _vec_len(v)	__vec_len ((void *) (v))
#define vec_len(v)	((v) ? _vec_len(v) : 0)

u32 vec_len_not_inline (void *v);

/** \brief Number of data bytes in vector. */

#define vec_bytes(v) (vec_len (v) * sizeof (v[0]))

/**
 * Return size of memory allocated for the vector
 *
 * @param v vector
 * @return memory size allocated for the vector
 */

uword vec_mem_size (void *v);

/**
 * Number of elements that can fit into generic vector
 *
 * @param v vector
 * @param b extra header bytes
 * @return number of elements that can fit into vector
 */

always_inline uword
vec_max_bytes (void *v)
{
  return v ? vec_mem_size (v) - vec_get_header_size (v) : 0;
}

always_inline uword
_vec_max_len (void *v, uword elt_sz)
{
  return vec_max_bytes (v) / elt_sz;
}

#define vec_max_len(v) _vec_max_len (v, _vec_elt_sz (v))

static_always_inline void
_vec_set_grow_elts (void *v, uword n_elts)
{
  uword max = pow2_mask (BITS (_vec_find (0)->grow_elts));

  if (PREDICT_FALSE (n_elts > max))
    n_elts = max;

  _vec_find (v)->grow_elts = n_elts;
}

always_inline void
_vec_set_len (void *v, uword len, uword elt_sz)
{
  ASSERT (v);
  ASSERT (len <= _vec_max_len (v, elt_sz));
  uword old_len = _vec_len (v);
  uword grow_elts = _vec_find (v)->grow_elts;

  if (len > old_len)
    clib_mem_unpoison (v + old_len * elt_sz, (len - old_len) * elt_sz);
  else if (len > old_len)
    clib_mem_poison (v + len * elt_sz, (old_len - len) * elt_sz);

  _vec_set_grow_elts (v, old_len + grow_elts - len);
  _vec_find (v)->len = len;
}

#define vec_set_len(v, l) _vec_set_len ((void *) v, l, _vec_elt_sz (v))
#define vec_inc_len(v, l) vec_set_len (v, _vec_len (v) + (l))
#define vec_dec_len(v, l) vec_set_len (v, _vec_len (v) - (l))

/** \brief Reset vector length to zero
    NULL-pointer tolerant
*/
#define vec_reset_length(v) do { if (v) vec_set_len (v, 0); } while (0)

/** \brief End (last data address) of vector. */
#define vec_end(v)	((v) + vec_len (v))

/** \brief True if given pointer is within given vector. */
#define vec_is_member(v,e) ((e) >= (v) && (e) < vec_end (v))

/** \brief Get vector value at index i checking that i is in bounds. */
#define vec_elt_at_index(v,i)			\
({						\
  ASSERT ((i) < vec_len (v));			\
  (v) + (i);					\
})

/** \brief Get vector value at index i */
#define vec_elt(v,i) (vec_elt_at_index(v,i))[0]

/** \brief Vector iterator */
#define vec_foreach(var,vec) for (var = (vec); var < vec_end (vec); var++)

/** \brief Vector iterator (reverse) */
#define vec_foreach_backwards(var, vec)                                       \
  if (vec)                                                                    \
    for (var = vec_end (vec) - 1; var >= (vec); var--)

/** \brief Iterate over vector indices. */
#define vec_foreach_index(var,v) for ((var) = 0; (var) < vec_len (v); (var)++)

/** \brief Iterate over vector indices (reverse). */
#define vec_foreach_index_backwards(var, v)                                   \
  if (v)                                                                      \
    for ((var) = vec_len ((v)) - 1; (var) >= 0; (var)--)

#endif /* included_clib_vec_bootstrap_h */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
