-
Notifications
You must be signed in to change notification settings - Fork 1
/
int.cc
91 lines (82 loc) · 2.05 KB
/
int.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#define ICI_CORE
#include "int.h"
#include "archiver.h"
#include "fwd.h"
#include "primes.h"
namespace ici
{
integer *small_ints[small_int_count];
/*
* Return the int object with the value 'v'. The returned object has had its
* ref count incremented. Returns nullptr on error, usual convention. Note that
* ints are intrinsically atomic, so if the given integer already exists, it
* will just incref it and return it.
*
* Note, 0 and 1 are available directly as 'o_zero' and 'o_one'.
*
* This --func-- forms part of the --ici-api--.
*/
integer *new_int(int64_t i)
{
object *o;
object **po;
if ((i & ~small_int_mask) == 0 && (o = small_ints[i]) != nullptr)
{
incref(o);
return intof(o);
}
for (po = &atoms[atom_hash_index((unsigned long)i * INT_PRIME)]; (o = *po) != nullptr;
--po < atoms ? po = atoms + atomsz - 1 : nullptr)
{
if (isint(o) && intof(o)->i_value == i)
{
incref(o);
return intof(o);
}
}
++supress_collect;
if ((o = ici_talloc(integer)) == nullptr)
{
--supress_collect;
return nullptr;
}
set_tfnz(o, TC_INT, object::O_ATOM, 1, sizeof(integer));
rego(o);
intof(o)->i_value = i;
--supress_collect;
store_atom_and_count(po, o);
return intof(o);
}
/*
* Returns 0 if these objects are equal, else non-zero.
* See the comments on t_cmp() in object.h.
*/
int int_type::cmp(object *o1, object *o2)
{
return intof(o1)->i_value != intof(o2)->i_value;
}
/*
* Return a hash sensitive to the value of the object.
* See the comment on t_hash() in object.h
*/
unsigned long int_type::hash(object *o)
{
/*
* There are in-line versions of this in object.c and binop.h.
*/
return (unsigned long)intof(o)->i_value * INT_PRIME;
}
int int_type::save(archiver *ar, object *obj)
{
return ar->write(intof(obj)->i_value);
}
object *int_type::restore(archiver *ar)
{
int64_t value;
if (ar->read(&value))
{
return nullptr;
}
return new_int(value);
}
} // namespace ici