Add vvalptridx_t for always-valid valptridx values
This commit is contained in:
parent
125d9257be
commit
915b78b5e1
|
@ -103,7 +103,7 @@ protected:
|
|||
static index_type check_index_range(const A &a, index_type s) __attribute_warn_unused_result;
|
||||
pointer_type p;
|
||||
index_type i;
|
||||
static decltype(get_global_array(pointer_type())) get_array()
|
||||
static constexpr decltype(get_global_array(pointer_type())) get_array()
|
||||
{
|
||||
return get_global_array(pointer_type());
|
||||
}
|
||||
|
@ -124,19 +124,85 @@ typename valptridx_t<T, I, magic_constant>::index_type valptridx_t<T, I, magic_c
|
|||
return DXX_VALPTRIDX_CHECK(static_cast<std::size_t>(s) < a.size(), "invalid index used in array subscript", s, index_range_exception);
|
||||
}
|
||||
|
||||
template <typename T, typename I, template <I> class magic_constant>
|
||||
class vvalptridx_t : public valptridx_t<T, I, magic_constant>
|
||||
{
|
||||
typedef valptridx_t<T, I, magic_constant> base_t;
|
||||
protected:
|
||||
using base_t::get_array;
|
||||
using base_t::check_index_range;
|
||||
using base_t::index_range_exception;
|
||||
public:
|
||||
typedef typename base_t::pointer_type pointer_type;
|
||||
typedef typename base_t::index_type index_type;
|
||||
template <index_type v>
|
||||
static constexpr const magic_constant<v> &check_constant_index(const magic_constant<v> &m)
|
||||
{
|
||||
return DXX_VALPTRIDX_CHECK(static_cast<std::size_t>(v) < get_array().size(), "invalid index used", m, index_range_exception);
|
||||
}
|
||||
vvalptridx_t() = delete;
|
||||
template <typename A>
|
||||
vvalptridx_t(A &a, pointer_type t, index_type s) :
|
||||
base_t(a, t, s)
|
||||
{
|
||||
}
|
||||
template <index_type v>
|
||||
vvalptridx_t(const magic_constant<v> &m) :
|
||||
base_t(check_constant_index(m))
|
||||
{
|
||||
}
|
||||
vvalptridx_t(const vvalptridx_t<typename tt::remove_const<T>::type, I, magic_constant> &t) :
|
||||
base_t(t)
|
||||
{
|
||||
}
|
||||
vvalptridx_t(pointer_type p) :
|
||||
base_t(p)
|
||||
{
|
||||
}
|
||||
vvalptridx_t(const base_t &t) :
|
||||
base_t(get_array(), t, t)
|
||||
{
|
||||
}
|
||||
template <typename A>
|
||||
vvalptridx_t(A &a, index_type s) :
|
||||
base_t(check_index_range(a, s))
|
||||
{
|
||||
}
|
||||
vvalptridx_t(index_type s) :
|
||||
base_t(check_index_range(get_array(), s))
|
||||
{
|
||||
}
|
||||
using base_t::operator==;
|
||||
template <index_type v>
|
||||
bool operator==(const magic_constant<v> &m) const
|
||||
{
|
||||
return base_t::operator==(check_constant_index(m));
|
||||
}
|
||||
template <typename R>
|
||||
bool operator!=(const R &rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
#define _DEFINE_VALPTRIDX_SUBTYPE_USERTYPE(N,P,I,A,name,Pconst) \
|
||||
static inline decltype(A) Pconst &get_global_array(P Pconst*) { return A; } \
|
||||
static inline constexpr decltype(A) Pconst &get_global_array(P Pconst*) { return A; } \
|
||||
\
|
||||
struct name : valptridx_t<P Pconst, I, P##_magic_constant_t> { \
|
||||
name() = delete; \
|
||||
DXX_INHERIT_CONSTRUCTORS(name, valptridx_t<P Pconst, I, P##_magic_constant_t>); \
|
||||
}; \
|
||||
\
|
||||
static inline name N(name::pointer_type o, name::index_type i) { \
|
||||
struct v##name : vvalptridx_t<P Pconst, I, P##_magic_constant_t> { \
|
||||
v##name() = delete; \
|
||||
DXX_INHERIT_CONSTRUCTORS(v##name, vvalptridx_t<P Pconst, I, P##_magic_constant_t>); \
|
||||
}; \
|
||||
\
|
||||
static inline v##name N(name::pointer_type o, name::index_type i) { \
|
||||
return {A, o, i}; \
|
||||
} \
|
||||
\
|
||||
static inline name operator-(P Pconst *o, decltype(A) &O) \
|
||||
static inline v##name operator-(P Pconst *o, decltype(A) &O) \
|
||||
{ \
|
||||
return N(o, const_cast<const P *>(o) - &(const_cast<const decltype(A) &>(O).front())); \
|
||||
} \
|
||||
|
@ -146,4 +212,8 @@ typename valptridx_t<T, I, magic_constant>::index_type valptridx_t<T, I, magic_c
|
|||
#define DEFINE_VALPTRIDX_SUBTYPE(N,P,I,A) \
|
||||
_DEFINE_VALPTRIDX_SUBTYPE_USERTYPE(N,P,I,A,N##_t,); \
|
||||
_DEFINE_VALPTRIDX_SUBTYPE_USERTYPE(N,P,I,A,c##N##_t,const); \
|
||||
\
|
||||
static inline v##N##_t N(N##_t::index_type i) { \
|
||||
return {A, i}; \
|
||||
} \
|
||||
|
||||
|
|
|
@ -653,17 +653,17 @@ int obj_get_new_seg(object *obj);
|
|||
|
||||
// when an object has moved into a new segment, this function unlinks it
|
||||
// from its old segment, and links it into the new segment
|
||||
void obj_relink(objptridx_t objnum,segnum_t newsegnum);
|
||||
void obj_relink(vobjptridx_t objnum,segnum_t newsegnum);
|
||||
|
||||
// for getting out of messed up linking situations (i.e. caused by demo playback)
|
||||
void obj_relink_all(void);
|
||||
|
||||
// links an object into a segment's list of objects.
|
||||
// takes object number and segment number
|
||||
void obj_link(objptridx_t objnum,segnum_t segnum);
|
||||
void obj_link(vobjptridx_t objnum,segnum_t segnum);
|
||||
|
||||
// unlinks an object from a segment's list of objects
|
||||
void obj_unlink(objptridx_t objnum);
|
||||
void obj_unlink(vobjptridx_t objnum);
|
||||
|
||||
// initialize a new object. adds to the list for the given segment
|
||||
// returns the object number
|
||||
|
@ -675,7 +675,7 @@ objptridx_t obj_create(enum object_type_t type, ubyte id, segnum_t segnum, const
|
|||
objptridx_t obj_create_copy(objnum_t objnum, vms_vector *new_pos, segnum_t newsegnum);
|
||||
|
||||
// remove object from the world
|
||||
void obj_delete(objptridx_t objnum);
|
||||
void obj_delete(vobjptridx_t objnum);
|
||||
|
||||
// called after load. Takes number of objects, and objects should be
|
||||
// compressed
|
||||
|
|
|
@ -1023,7 +1023,7 @@ static int load_game_data(PHYSFS_file *LoadFile)
|
|||
}
|
||||
else {
|
||||
Objects[i].segnum = segment_none; //avoid Assert()
|
||||
obj_link(objptridx(&Objects[i],i),objsegnum);
|
||||
obj_link(objptridx(i),objsegnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ using std::min;
|
|||
using std::max;
|
||||
|
||||
static void obj_detach_all(object *parent);
|
||||
static void obj_detach_one(objptridx_t sub);
|
||||
static void obj_detach_one(vobjptridx_t sub);
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
|
@ -890,14 +890,10 @@ void special_reset_objects(void)
|
|||
}
|
||||
|
||||
//link the object into the list for its segment
|
||||
void obj_link(objptridx_t obj,segnum_t segnum)
|
||||
void obj_link(vobjptridx_t obj,segnum_t segnum)
|
||||
{
|
||||
Assert(obj != object_none);
|
||||
|
||||
Assert(obj->segnum == segment_none);
|
||||
|
||||
Assert(segnum>=0 && segnum<=Highest_segment_index);
|
||||
|
||||
obj->segnum = segnum;
|
||||
|
||||
obj->next = Segments[segnum].objects;
|
||||
|
@ -919,12 +915,9 @@ void obj_link(objptridx_t obj,segnum_t segnum)
|
|||
Objects[0].prev = object_none;
|
||||
}
|
||||
|
||||
void obj_unlink(objptridx_t obj)
|
||||
void obj_unlink(vobjptridx_t obj)
|
||||
{
|
||||
segment *seg = &Segments[obj->segnum];
|
||||
|
||||
Assert(obj != object_none);
|
||||
|
||||
if (obj->prev == object_none)
|
||||
seg->objects = obj->next;
|
||||
else
|
||||
|
@ -1242,9 +1235,8 @@ objptridx_t obj_create_copy(objnum_t objnum, vms_vector *new_pos, segnum_t newse
|
|||
#endif
|
||||
|
||||
//remove object from the world
|
||||
void obj_delete(objptridx_t obj)
|
||||
void obj_delete(vobjptridx_t obj)
|
||||
{
|
||||
Assert(obj != object_none);
|
||||
Assert(obj->type != OBJ_NONE);
|
||||
Assert(obj != ConsoleObject);
|
||||
|
||||
|
@ -1589,16 +1581,12 @@ void obj_delete_all_that_should_be_dead()
|
|||
|
||||
//when an object has moved into a new segment, this function unlinks it
|
||||
//from its old segment, and links it into the new segment
|
||||
void obj_relink(objptridx_t objnum,segnum_t newsegnum)
|
||||
void obj_relink(vobjptridx_t objnum,segnum_t newsegnum)
|
||||
{
|
||||
|
||||
Assert((objnum >= 0) && (objnum <= Highest_object_index));
|
||||
Assert((newsegnum <= Highest_segment_index) && (newsegnum >= 0));
|
||||
|
||||
obj_unlink(objnum);
|
||||
|
||||
obj_link(objnum,newsegnum);
|
||||
|
||||
}
|
||||
|
||||
// for getting out of messed up linking situations (i.e. caused by demo playback)
|
||||
|
@ -2095,7 +2083,7 @@ void obj_attach(objptridx_t parent,objptridx_t sub)
|
|||
}
|
||||
|
||||
//dettaches one object
|
||||
void obj_detach_one(objptridx_t sub)
|
||||
void obj_detach_one(vobjptridx_t sub)
|
||||
{
|
||||
Assert(sub->flags & OF_ATTACHED);
|
||||
Assert(sub->ctype.expl_info.attach_parent != object_none);
|
||||
|
|
Loading…
Reference in a new issue