12#include <initializer_list>
31 using difference_type = ptrdiff_t;
32 using iterator_category = std::bidirectional_iterator_tag;
34 iterator(
const TclObject& obj_,
unsigned i_)
35 : obj(&obj_), i(i_) {}
37 [[nodiscard]]
bool operator==(
const iterator& other)
const {
38 assert(obj == other.obj);
43 return obj->getListIndexUnchecked(i).getString();
46 iterator& operator++() {
50 iterator operator++(
int) {
51 iterator result = *
this;
55 iterator& operator--() {
59 iterator operator--(
int) {
60 iterator result = *
this;
72 template<
typename T>
explicit TclObject(T
t) { init(newObj(
t)); }
77 template<
typename... Args>
79 init(newList({newObj(std::forward<Args>(args))...}));
83 template<
typename... Args>
85 init(Tcl_NewDictObj());
94 Tcl_DecrRefCount(obj);
100 if (&other !=
this) {
101 Tcl_DecrRefCount(obj);
107 std::swap(obj, other.obj);
112 if (Tcl_IsShared(obj)) {
113 Tcl_DecrRefCount(obj);
114 obj = newObj(std::forward<T>(
t));
115 Tcl_IncrRefCount(obj);
117 assign(std::forward<T>(
t));
129 addListElementsImpl(first, last,
130 typename std::iterator_traits<ITER>::iterator_category());
136 addListElementsImpl({newObj(std::forward<Args>(args))...});
140 template<
typename Key,
typename Value>
154 [[nodiscard]] std::span<const uint8_t>
getBinary()
const;
161 template<
typename Key>
173 [[nodiscard]]
unsigned size()
const {
return getListLengthUnchecked(); }
174 [[nodiscard]]
bool empty()
const {
return size() == 0; }
175 [[nodiscard]] iterator
begin()
const {
return {*
this, 0}; }
176 [[nodiscard]] iterator
end()
const {
return {*
this,
size()}; }
199 void init(Tcl_Obj* obj_)
noexcept {
201 Tcl_IncrRefCount(obj);
204 [[nodiscard]]
static Tcl_Obj* newObj(std::string_view s) {
205 return Tcl_NewStringObj(s.data(),
int(s.size()));
207 [[nodiscard]]
static Tcl_Obj* newObj(
const char* s) {
208 return Tcl_NewStringObj(s,
int(strlen(s)));
210 [[nodiscard]]
static Tcl_Obj* newObj(
bool b) {
211 return Tcl_NewBooleanObj(b);
213 [[nodiscard]]
static Tcl_Obj* newObj(
int i) {
214 return Tcl_NewIntObj(i);
216 [[nodiscard]]
static Tcl_Obj* newObj(
unsigned u) {
217 return Tcl_NewIntObj(narrow_cast<int>(u));
219 [[nodiscard]]
static Tcl_Obj* newObj(
float f) {
220 return Tcl_NewDoubleObj(
double(f));
222 [[nodiscard]]
static Tcl_Obj* newObj(
double d) {
223 return Tcl_NewDoubleObj(d);
225 [[nodiscard]]
static Tcl_Obj* newObj(std::span<const uint8_t> buf) {
226 return Tcl_NewByteArrayObj(buf.data(),
int(buf.size()));
228 [[nodiscard]]
static Tcl_Obj* newObj(
const TclObject& o) {
231 [[nodiscard]]
static Tcl_Obj* newList(std::initializer_list<Tcl_Obj*> l) {
232 return Tcl_NewListObj(
int(l.size()), l.begin());
235 void assign(std::string_view s) {
236 Tcl_SetStringObj(obj, s.data(),
int(s.size()));
238 void assign(
const char* s) {
239 Tcl_SetStringObj(obj, s,
int(strlen(s)));
241 void assign(
bool b) {
242 Tcl_SetBooleanObj(obj, b);
245 Tcl_SetIntObj(obj, i);
247 void assign(
unsigned u) {
248 Tcl_SetIntObj(obj, narrow_cast<int>(u));
250 void assign(
float f) {
251 Tcl_SetDoubleObj(obj,
double(f));
253 void assign(
double d) {
254 Tcl_SetDoubleObj(obj, d);
256 void assign(std::span<const uint8_t> b) {
257 Tcl_SetByteArrayObj(obj, b.data(),
int(b.size()));
260 template<
typename ITER>
261 void addListElementsImpl(ITER first, ITER last, std::input_iterator_tag) {
262 for (ITER it = first; it != last; ++it) {
266 template<
typename ITER>
267 void addListElementsImpl(ITER first, ITER last, std::random_access_iterator_tag) {
268 auto objc = last - first;
269 if (objc == 0)
return;
270 VLA(Tcl_Obj*, objv, objc);
271 std::transform(first, last, objv.data(), [](
const auto&
t) { return newObj(t); });
272 addListElementsImpl(narrow<int>(objc), objv.data());
276 void addListElementsImpl(
int objc, Tcl_Obj*
const* objv);
277 void addListElementsImpl(std::initializer_list<Tcl_Obj*> l);
279 [[nodiscard]]
unsigned getListLengthUnchecked()
const;
286static_assert(
sizeof(TclObject) ==
sizeof(Tcl_Obj*));
288template<
typename... Args>
294template<
typename... Args>
301 [[nodiscard]] uint32_t
operator()(std::string_view str)
const {
bool getBoolean(Interpreter &interp) const
TclObject executeCommand(Interpreter &interp, bool compile=false)
Interpret this TclObject as a command and execute it.
TclObject & operator=(const TclObject &other)
unsigned getListLength(Interpreter &interp) const
friend bool operator==(const TclObject &x, const TclObject &y)
TclObject getListIndexUnchecked(unsigned index) const
TclObject getListIndex(Interpreter &interp, unsigned index) const
bool evalBool(Interpreter &interp) const
std::optional< TclObject > getOptionalDictValue(const TclObject &key) const
void removeListIndex(Interpreter &interp, unsigned index)
TclObject(const TclObject &o)
double getDouble(Interpreter &interp) const
TclObject(TclObject &&o) noexcept
void addListElement(Args &&... args)
float getFloat(Interpreter &interp) const
TclObject & operator=(TclObject &other)
TclObject eval(Interpreter &interp) const
void addListElements(Range &&range)
TclObject(MakeListTag, Args &&... args)
void addListElement(const T &t)
std::span< const uint8_t > getBinary() const
std::optional< float > getOptionalFloat() const
void addListElements(ITER first, ITER last)
TclObject getDictValue(Interpreter &interp, const Key &key) const
Tcl_Obj * getTclObjectNonConst() const
int getInt(Interpreter &interp) const
TclObject & operator=(T &&t)
TclObject(MakeDictTag, Args &&... args)
friend bool operator==(const TclObject &x, std::string_view y)
void addDictKeyValue(const Key &key, const Value &value)
void addDictKeyValues(Args &&... args)
std::optional< bool > getOptionalBool() const
TclObject getDictValue(Interpreter &interp, const TclObject &key) const
std::optional< int > getOptionalInt() const
zstring_view getString() const
TclObject & operator=(TclObject &&other) noexcept
std::optional< double > getOptionalDouble() const
void setDictValue(Interpreter &interp, const TclObject &key, const TclObject &value)
Like std::string_view, but with the extra guarantee that it refers to a zero-terminated string.
This file implemented 3 utility functions:
TclObject makeTclList(Args &&... args)
TclObject makeTclDict(Args &&... args)
uint32_t operator()(std::string_view str) const
uint32_t operator()(const TclObject &obj) const
constexpr uint128 operator*(const uint128 &a, const uint128 &b)
#define VLA(TYPE, NAME, LENGTH)
uint32_t xxhash(std::string_view key)