__PREFIX_BEGIN__
//-----------------------------------------------------------------------------
// Copyright © 2003 - Philip Howard - All rights reserved
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//-----------------------------------------------------------------------------
// package	libh/map
// homepage	http://libh.slashusr.org/
//-----------------------------------------------------------------------------
// author	Philip Howard
// email	libh at ipal dot org
// homepage	http://phil.ipal.org/
//-----------------------------------------------------------------------------
// This file is best viewed using a fixed spaced font such as Courier
// and in a display at least 120 columns wide.
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// file		map.h
//
// purpose	Define resources for the Data Mapping library package.
//-----------------------------------------------------------------------------
#ifndef __MAP_H__
#define __MAP_H__

__PREFIX_END__

__INCLUDE_BEGIN__
#include <ctype.h>

#include <libh/avl.h>

__INCLUDE_END__

__DEFINE_BEGIN__
//-----------------------------------------------------------------------------
// struct	map_root
// type		MAP
//
// purpose	This structure is the anchor point for a data mapping.
//		The pointer to it is the mapping handle.
//-----------------------------------------------------------------------------
struct map_root {
    int ( *	cmp_func	)()	;
    int		options		;
    int		key_type	;
    avl_root	avl_tree	;
};
typedef struct map_root		map_t	;
typedef struct map_root		MAP_T	;
typedef struct map_root *	MAP	;
typedef struct map_root *	map_p	;
typedef struct map_root *	MAP_P	;

#define MAP_OPT_LOWER	1
#define MAP_OPT_UPPER	2
#define MAP_OPT_DIGITS	4
#define MAP_OPT_SPACES	8
#define MAP_OPT_PATHS	16

//-----------------------------------------------------------------------------
// struct	map_mixed
//
// purpose	This structure holds data for each node.
//-----------------------------------------------------------------------------
struct map_mixed {
    union map_data {
	union map_scalar {
	    signed char		sc	;
	    unsigned char	uc	;
	    signed short	ss	;
	    unsigned short	us	;
	    signed int		si	;
	    unsigned int	ui	;
	    signed long		sl	;
	    unsigned long	ul	;
	    signed long long	sll	;
	    unsigned long long	ull	;
	    double		d	;
	    long double		ld	;
	    void *		ptr	;
	    MAP			map	;
	}		scalar	;
	struct map_array {
	    void *		ptr	;
	    size_t		len	;
	    char		dup	;
	}		array	;
    }		mix	;
    int		type	;
};
typedef struct map_mixed	map_mixed	;

__DEFINE_END__

__ALIAS_BEGIN__
//-----------------------------------------------------------------------------
// macro	map_from_avl
//
// purpose	Given a pointer to the avl_root structure, yield a pointer to
//		the map_root structure that contains it.  This requires a
//		backwards offset calculation and may result in alignment
//		warnings on some platforms.
//-----------------------------------------------------------------------------
#define map_from_avl(p) ((map_p)((void*)(((char*)(p))-((size_t)(&(((map_p)0)->avl_tree))))))

//-----------------------------------------------------------------------------
// macro	map_cmp_func
//
// purpose	Given a pointer to the avl_tree member (e.g. what the avl layer
//		passes as the 3rd argument in the avl comparison function),
//		yield the function pointer to the alternate comparison function
//		set up for that avl_tree.
//-----------------------------------------------------------------------------
#define map_cmp_func(p) (map_from_avl((p))->cmp_func)

__ALIAS_END__

__FMACRO_BEGIN__
//-----------------------------------------------------------------------------
// Define various macros to describe generic type properties.
//-----------------------------------------------------------------------------
#define MAP_DATA_SIGNED		0x00000100
#define MAP_DATA_UNSIGNED	0x00000200

#define MAP_DATA_INTEGER	0x00000400
#define MAP_DATA_FLOAT		0x00000800
#define MAP_DATA_OTHER		0x00001000

#define MAP_DATA_SCALAR		0x00002000
#define MAP_DATA_ARRAY		0x00004000
#define MAP_DATA_STRING		MAP_DATA_ARRAY

//-----------------------------------------------------------------------------
// Specific data type codes are defined as their size values.  This results in
// equivalent types being assigned the same type code on any given platform.
//-----------------------------------------------------------------------------
#define MAP_DATA_DOUBLE		(sizeof(double))
#define MAP_DATA_LONG_DOUBLE	(sizeof(long double))

#define MAP_DATA_CHAR		(sizeof(char))
#define MAP_DATA_SHORT		(sizeof(short))
#define MAP_DATA_INT		(sizeof(int))
#define MAP_DATA_LONG		(sizeof(long))
#define MAP_DATA_LONG_LONG	(sizeof(long long))

#define MAP_DATA_POINTER	(sizeof(void *))
#define MAP_DATA_MAPPTR		(sizeof(map_p))

//-----------------------------------------------------------------------------
// Define macros that can be used to isolate generic properties of a type.
//-----------------------------------------------------------------------------
#define map_type_is_signed(t)		\
	(((t)&((MAP_DATA_SIGNED)|(MAP_DATA_UNSIGNED)))==(MAP_DATA_SIGNED))
#define map_type_is_unsigned(t)		\
	(((t)&((MAP_DATA_SIGNED)|(MAP_DATA_UNSIGNED)))==(MAP_DATA_UNSIGNED))

#define map_type_is_integer(t)		\
	(((t)&((MAP_DATA_INTEGER)|(MAP_DATA_FLOAT)|(MAP_DATA_OTHER)))==(MAP_DATA_INTEGER))
#define map_type_is_float(t)		\
	(((t)&((MAP_DATA_INTEGER)|(MAP_DATA_FLOAT)|(MAP_DATA_OTHER)))==(MAP_DATA_FLOAT))

#define map_type_is_scalar(t)		\
	(((t)&((MAP_DATA_SCALAR)|(MAP_DATA_ARRAY)))==(MAP_DATA_SCALAR))
#define map_type_is_array(t)		\
	(((t)&((MAP_DATA_SCALAR)|(MAP_DATA_ARRAY)))==(MAP_DATA_ARRAY))
#define map_type_is_string(t)		\
	(((t)&((MAP_DATA_SCALAR)|(MAP_DATA_ARRAY)))==(MAP_DATA_ARRAY))

#define map_type_sizeof(t)	((t)&(0x000000ff))

//-----------------------------------------------------------------------------
// Define macros for each individual type constructed from its properties.
//-----------------------------------------------------------------------------
#define MAP_DATA_SC	MAP_DATA_SCALAR+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_CHAR
#define MAP_DATA_UC	MAP_DATA_SCALAR+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_CHAR
#define MAP_DATA_SS	MAP_DATA_SCALAR+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_SHORT
#define MAP_DATA_US	MAP_DATA_SCALAR+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_SHORT
#define MAP_DATA_SI	MAP_DATA_SCALAR+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_INT
#define MAP_DATA_UI	MAP_DATA_SCALAR+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_INT
#define MAP_DATA_SL	MAP_DATA_SCALAR+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_LONG
#define MAP_DATA_UL	MAP_DATA_SCALAR+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_LONG
#define MAP_DATA_SLL	MAP_DATA_SCALAR+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_LONG_LONG
#define MAP_DATA_ULL	MAP_DATA_SCALAR+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_LONG_LONG
#define MAP_DATA_C	MAP_DATA_UC

#define MAP_DATA_D	MAP_DATA_SCALAR+MAP_DATA_FLOAT+MAP_DATA_DOUBLE
#define MAP_DATA_LD	MAP_DATA_SCALAR+MAP_DATA_FLOAT+MAP_DATA_LONG_DOUBLE

#define MAP_DATA_PTR	MAP_DATA_SCALAR+MAP_DATA_OTHER+MAP_DATA_POINTER
#define MAP_DATA_MAP	MAP_DATA_SCALAR+MAP_DATA_OTHER+MAP_DATA_MAPPTR

#define MAP_DATA_SCA	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_CHAR
#define MAP_DATA_UCA	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_CHAR
#define MAP_DATA_SSA	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_SHORT
#define MAP_DATA_USA	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_SHORT
#define MAP_DATA_SIA	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_INT
#define MAP_DATA_UIA	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_INT
#define MAP_DATA_SLA	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_LONG
#define MAP_DATA_ULA	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_LONG
#define MAP_DATA_SLLA	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_LONG_LONG
#define MAP_DATA_ULLA	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_LONG_LONG
#define MAP_DATA_CA	MAP_DATA_UCA

#define MAP_DATA_DA	MAP_DATA_ARRAY+MAP_DATA_FLOAT+MAP_DATA_DOUBLE
#define MAP_DATA_LDA	MAP_DATA_ARRAY+MAP_DATA_FLOAT+MAP_DATA_LONG_DOUBLE

#define MAP_DATA_SCS	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_CHAR
#define MAP_DATA_UCS	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_CHAR
#define MAP_DATA_SSS	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_SHORT
#define MAP_DATA_USS	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_SHORT
#define MAP_DATA_SIS	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_INT
#define MAP_DATA_UIS	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_INT
#define MAP_DATA_SLS	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_LONG
#define MAP_DATA_ULS	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_LONG
#define MAP_DATA_SLLS	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_SIGNED+MAP_DATA_LONG_LONG
#define MAP_DATA_ULLS	MAP_DATA_ARRAY+MAP_DATA_INTEGER+MAP_DATA_UNSIGNED+MAP_DATA_LONG_LONG
#define MAP_DATA_CS	MAP_DATA_UCS
#define MAP_DATA_STR	MAP_DATA_UCS

#define MAP_DATA_DS	MAP_DATA_ARRAY+MAP_DATA_FLOAT+MAP_DATA_DOUBLE
#define MAP_DATA_LDS	MAP_DATA_ARRAY+MAP_DATA_FLOAT+MAP_DATA_LONG_DOUBLE

__FMACRO_END__


__SUFFIX_BEGIN__
//-----------------------------------------------------------------------------
// end of map.h
//-----------------------------------------------------------------------------

#endif /* __MAP_H__ */

__SUFFIX_END__

