
/*** <<< INCLUDES [T1] >>> ***/

#include <INTEGER.h>
#include <constr_SET.h>

/*** <<< DEPS [T1] >>> ***/


/*
 * Method of determining the components presence
 */
typedef enum T1_PR {
	T1_PR_i,	/* Member i is present */
} T1_PR;

/*** <<< TYPE-DECLS [T1] >>> ***/

typedef struct T1 {
	INTEGER_t	 i;
	/*
	 * This type is extensible,
	 * possible extensions are below.
	 */
	
	/* Presence bitmask: ASN_SET_ISPRESENT(pT1, T1_PR_x) */
	unsigned int _presence_map
		[((1+(8*sizeof(unsigned int))-1)/(8*sizeof(unsigned int)))];
	
	/* Context for parsing across buffer boundaries */
	asn_struct_ctx_t _asn_ctx;
} T1_t;

/*** <<< FUNC-DECLS [T1] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_T1;

/*** <<< STAT-DEFS [T1] >>> ***/

static asn_TYPE_member_t asn_MBR_T1_1[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct T1, i),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
		.tag_mode = 0,
		.type = (void *)&asn_DEF_INTEGER,
		.memb_constraints = 0,	/* Defer constraints checking to the member type */
		.name = "i"
		},
};
static ber_tlv_tag_t asn_DEF_T1_1_tags[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (17 << 2))
};
static asn_TYPE_tag2member_t asn_MAP_T1_1_tag2el[] = {
    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 } /* i at 14 */
};
static uint8_t asn_MAP_T1_1_mmap[(1 + (8 * sizeof(unsigned int)) - 1) / 8] = {
	(1 << 7)
};
static asn_SET_specifics_t asn_SPC_T1_1_specs = {
	sizeof(struct T1),
	offsetof(struct T1, _asn_ctx),
	offsetof(struct T1, _presence_map),
	asn_MAP_T1_1_tag2el,
	1,	/* Count of tags in the map */
	asn_MAP_T1_1_tag2el,	/* Same as above */
	1,	/* Count of tags in the CXER map */
	1,	/* Whether extensible */
	(unsigned int *)asn_MAP_T1_1_mmap	/* Mandatory elements map */
};
asn_TYPE_descriptor_t asn_DEF_T1 = {
	"T1",
	"T1",
	SET_free,
	SET_print,
	SET_constraint,
	SET_decode_ber,
	SET_encode_der,
	SET_decode_xer,
	SET_encode_xer,
	0,	/* Use generic outmost tag fetcher */
	asn_DEF_T1_1_tags,
	sizeof(asn_DEF_T1_1_tags)
		/sizeof(asn_DEF_T1_1_tags[0]), /* 1 */
	asn_DEF_T1_1_tags,	/* Same as above */
	sizeof(asn_DEF_T1_1_tags)
		/sizeof(asn_DEF_T1_1_tags[0]), /* 1 */
	asn_MBR_T1_1,
	1,	/* Elements count */
	&asn_SPC_T1_1_specs	/* Additional specs */
};


/*** <<< INCLUDES [T2] >>> ***/

#include <INTEGER.h>
#include <constr_SET.h>

/*** <<< DEPS [T2] >>> ***/


/*
 * Method of determining the components presence
 */
typedef enum T2_PR {
	T2_PR_i,	/* Member i is present */
} T2_PR;

/*** <<< TYPE-DECLS [T2] >>> ***/

typedef struct T2 {
	INTEGER_t	 i;
	/*
	 * This type is extensible,
	 * possible extensions are below.
	 */
	
	/* Presence bitmask: ASN_SET_ISPRESENT(pT2, T2_PR_x) */
	unsigned int _presence_map
		[((1+(8*sizeof(unsigned int))-1)/(8*sizeof(unsigned int)))];
	
	/* Context for parsing across buffer boundaries */
	asn_struct_ctx_t _asn_ctx;
} T2_t;

/*** <<< FUNC-DECLS [T2] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_T2;

/*** <<< STAT-DEFS [T2] >>> ***/

static asn_TYPE_member_t asn_MBR_T2_1[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct T2, i),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
		.tag_mode = 0,
		.type = (void *)&asn_DEF_INTEGER,
		.memb_constraints = 0,	/* Defer constraints checking to the member type */
		.name = "i"
		},
};
static ber_tlv_tag_t asn_DEF_T2_1_tags[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (17 << 2))
};
static asn_TYPE_tag2member_t asn_MAP_T2_1_tag2el[] = {
    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 } /* i at 15 */
};
static uint8_t asn_MAP_T2_1_mmap[(1 + (8 * sizeof(unsigned int)) - 1) / 8] = {
	(1 << 7)
};
static asn_SET_specifics_t asn_SPC_T2_1_specs = {
	sizeof(struct T2),
	offsetof(struct T2, _asn_ctx),
	offsetof(struct T2, _presence_map),
	asn_MAP_T2_1_tag2el,
	1,	/* Count of tags in the map */
	asn_MAP_T2_1_tag2el,	/* Same as above */
	1,	/* Count of tags in the CXER map */
	1,	/* Whether extensible */
	(unsigned int *)asn_MAP_T2_1_mmap	/* Mandatory elements map */
};
asn_TYPE_descriptor_t asn_DEF_T2 = {
	"T2",
	"T2",
	SET_free,
	SET_print,
	SET_constraint,
	SET_decode_ber,
	SET_encode_der,
	SET_decode_xer,
	SET_encode_xer,
	0,	/* Use generic outmost tag fetcher */
	asn_DEF_T2_1_tags,
	sizeof(asn_DEF_T2_1_tags)
		/sizeof(asn_DEF_T2_1_tags[0]), /* 1 */
	asn_DEF_T2_1_tags,	/* Same as above */
	sizeof(asn_DEF_T2_1_tags)
		/sizeof(asn_DEF_T2_1_tags[0]), /* 1 */
	asn_MBR_T2_1,
	1,	/* Elements count */
	&asn_SPC_T2_1_specs	/* Additional specs */
};


/*** <<< INCLUDES [T3] >>> ***/

#include <INTEGER.h>
#include <constr_CHOICE.h>

/*** <<< DEPS [T3] >>> ***/

typedef enum T3_PR {
	T3_PR_NOTHING,	/* No components present */
	T3_PR_i,
	/* Extensions may appear below */
} T3_PR;

/*** <<< TYPE-DECLS [T3] >>> ***/

typedef struct T3 {
	T3_PR present;
	union {
		INTEGER_t	 i;
		/*
		 * This type is extensible,
		 * possible extensions are below.
		 */
	} choice;
	
	/* Context for parsing across buffer boundaries */
	asn_struct_ctx_t _asn_ctx;
} T3_t;

/*** <<< FUNC-DECLS [T3] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_T3;

/*** <<< STAT-DEFS [T3] >>> ***/

static asn_TYPE_member_t asn_MBR_T3_1[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct T3, choice.i),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
		.tag_mode = 0,
		.type = (void *)&asn_DEF_INTEGER,
		.memb_constraints = 0,	/* Defer constraints checking to the member type */
		.name = "i"
		},
};
static asn_TYPE_tag2member_t asn_MAP_T3_1_tag2el[] = {
    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 } /* i at 16 */
};
static asn_CHOICE_specifics_t asn_SPC_T3_1_specs = {
	sizeof(struct T3),
	offsetof(struct T3, _asn_ctx),
	offsetof(struct T3, present),
	sizeof(((struct T3 *)0)->present),
	asn_MAP_T3_1_tag2el,
	1,	/* Count of tags in the map */
	1	/* Whether extensible */
};
asn_TYPE_descriptor_t asn_DEF_T3 = {
	"T3",
	"T3",
	CHOICE_free,
	CHOICE_print,
	CHOICE_constraint,
	CHOICE_decode_ber,
	CHOICE_encode_der,
	CHOICE_decode_xer,
	CHOICE_encode_xer,
	CHOICE_outmost_tag,
	0,	/* No effective tags (pointer) */
	0,	/* No effective tags (count) */
	0,	/* No tags (pointer) */
	0,	/* No tags (count) */
	asn_MBR_T3_1,
	1,	/* Elements count */
	&asn_SPC_T3_1_specs	/* Additional specs */
};


/*** <<< INCLUDES [T4] >>> ***/

#include <INTEGER.h>
#include <constr_CHOICE.h>

/*** <<< DEPS [T4] >>> ***/

typedef enum T4_PR {
	T4_PR_NOTHING,	/* No components present */
	T4_PR_i,
	/* Extensions may appear below */
} T4_PR;

/*** <<< TYPE-DECLS [T4] >>> ***/

typedef struct T4 {
	T4_PR present;
	union {
		INTEGER_t	 i;
		/*
		 * This type is extensible,
		 * possible extensions are below.
		 */
	} choice;
	
	/* Context for parsing across buffer boundaries */
	asn_struct_ctx_t _asn_ctx;
} T4_t;

/*** <<< FUNC-DECLS [T4] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_T4;

/*** <<< STAT-DEFS [T4] >>> ***/

static asn_TYPE_member_t asn_MBR_T4_1[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct T4, choice.i),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
		.tag_mode = 0,
		.type = (void *)&asn_DEF_INTEGER,
		.memb_constraints = 0,	/* Defer constraints checking to the member type */
		.name = "i"
		},
};
static asn_TYPE_tag2member_t asn_MAP_T4_1_tag2el[] = {
    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 } /* i at 17 */
};
static asn_CHOICE_specifics_t asn_SPC_T4_1_specs = {
	sizeof(struct T4),
	offsetof(struct T4, _asn_ctx),
	offsetof(struct T4, present),
	sizeof(((struct T4 *)0)->present),
	asn_MAP_T4_1_tag2el,
	1,	/* Count of tags in the map */
	1	/* Whether extensible */
};
asn_TYPE_descriptor_t asn_DEF_T4 = {
	"T4",
	"T4",
	CHOICE_free,
	CHOICE_print,
	CHOICE_constraint,
	CHOICE_decode_ber,
	CHOICE_encode_der,
	CHOICE_decode_xer,
	CHOICE_encode_xer,
	CHOICE_outmost_tag,
	0,	/* No effective tags (pointer) */
	0,	/* No effective tags (count) */
	0,	/* No tags (pointer) */
	0,	/* No tags (count) */
	asn_MBR_T4_1,
	1,	/* Elements count */
	&asn_SPC_T4_1_specs	/* Additional specs */
};

