@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// This library is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -51,11 +53,11 @@ String String::VPrintf(char const *format, va_list ap) | |||||
size_t needed = vsnprintf(nullptr, 0, format, ap2) + 1; | size_t needed = vsnprintf(nullptr, 0, format, ap2) + 1; | ||||
#if defined va_copy || !defined _MSC_VER | #if defined va_copy || !defined _MSC_VER | ||||
/* do not call va_end() if va_copy() wasn’t called. */ | |||||
/* do not call va_end() if va_copy() wasn't called. */ | |||||
va_end(ap2); | va_end(ap2); | ||||
#endif | #endif | ||||
((Super &)ret).Reserve(needed); | |||||
((super &)ret).reserve(needed); | |||||
ret.m_count = needed; | ret.m_count = needed; | ||||
vsnprintf(&ret[0], needed, format, ap); | vsnprintf(&ret[0], needed, format, ap); | ||||
@@ -54,7 +54,7 @@ public: | |||||
m_count(0), | m_count(0), | ||||
m_reserved(0) | m_reserved(0) | ||||
{ | { | ||||
Reserve(list.size()); | |||||
reserve(list.size()); | |||||
for (auto elem : list) | for (auto elem : list) | ||||
push(elem); | push(elem); | ||||
} | } | ||||
@@ -70,7 +70,7 @@ public: | |||||
{ | { | ||||
/* Reserve the exact number of values instead of what the other | /* Reserve the exact number of values instead of what the other | ||||
* array had reserved. Just a method for not wasting too much. */ | * array had reserved. Just a method for not wasting too much. */ | ||||
Reserve(that.m_count); | |||||
reserve(that.m_count); | |||||
for (ptrdiff_t i = 0; i < that.m_count; i++) | for (ptrdiff_t i = 0; i < that.m_count; i++) | ||||
new(&m_data[i]) element_t(that[i]); | new(&m_data[i]) element_t(that[i]); | ||||
m_count = that.m_count; | m_count = that.m_count; | ||||
@@ -88,7 +88,7 @@ public: | |||||
/* If not enough space, reserve memory, overwrite the first | /* If not enough space, reserve memory, overwrite the first | ||||
* elements, then use placement new directly for the | * elements, then use placement new directly for the | ||||
* remaining elements. */ | * remaining elements. */ | ||||
Reserve(that.m_count); | |||||
reserve(that.m_count); | |||||
for (ptrdiff_t i = 0; i < m_count && i < that.m_count; i++) | for (ptrdiff_t i = 0; i < m_count && i < that.m_count; i++) | ||||
m_data[i] = element_t(that[i]); | m_data[i] = element_t(that[i]); | ||||
for (ptrdiff_t i = m_count; i < that.m_count; i++) | for (ptrdiff_t i = m_count; i < that.m_count; i++) | ||||
@@ -115,7 +115,7 @@ public: | |||||
array_base& operator+=(array_base const &that) | array_base& operator+=(array_base const &that) | ||||
{ | { | ||||
ptrdiff_t todo = that.m_count; | ptrdiff_t todo = that.m_count; | ||||
Reserve(m_count + todo); | |||||
reserve(m_count + todo); | |||||
for (ptrdiff_t i = 0; i < todo; i++) | for (ptrdiff_t i = 0; i < todo; i++) | ||||
new(&m_data[m_count + i]) element_t(that[i]); | new(&m_data[m_count + i]) element_t(that[i]); | ||||
m_count += todo; | m_count += todo; | ||||
@@ -125,7 +125,7 @@ public: | |||||
ARRAY operator+(ARRAY const &that) const | ARRAY operator+(ARRAY const &that) const | ||||
{ | { | ||||
ARRAY ret; | ARRAY ret; | ||||
ret.Reserve(m_count + that.m_count); | |||||
ret.reserve(m_count + that.m_count); | |||||
ret += *this; | ret += *this; | ||||
ret += that; | ret += that; | ||||
return ret; | return ret; | ||||
@@ -149,23 +149,23 @@ public: | |||||
return m_data[n]; | return m_data[n]; | ||||
} | } | ||||
inline element_t& Last() | |||||
inline element_t& last() | |||||
{ | { | ||||
ASSERT(m_count > 0); | ASSERT(m_count > 0); | ||||
return m_data[m_count - 1]; | return m_data[m_count - 1]; | ||||
} | } | ||||
inline element_t *Data() | |||||
inline element_t *data() | |||||
{ | { | ||||
return m_data; | return m_data; | ||||
} | } | ||||
inline element_t const *Data() const | |||||
inline element_t const *data() const | |||||
{ | { | ||||
return m_data; | return m_data; | ||||
} | } | ||||
inline element_t const& Last() const | |||||
inline element_t const& last() const | |||||
{ | { | ||||
ASSERT(m_count > 0); | ASSERT(m_count > 0); | ||||
return m_data[m_count - 1]; | return m_data[m_count - 1]; | ||||
@@ -176,7 +176,7 @@ public: | |||||
if (m_count >= m_reserved) | if (m_count >= m_reserved) | ||||
{ | { | ||||
T tmp = x; | T tmp = x; | ||||
Grow(); | |||||
grow(); | |||||
new (&m_data[m_count]) element_t(tmp); | new (&m_data[m_count]) element_t(tmp); | ||||
} | } | ||||
else | else | ||||
@@ -189,7 +189,7 @@ public: | |||||
inline array_base& operator>>(T const &x) | inline array_base& operator>>(T const &x) | ||||
{ | { | ||||
RemoveItem(x); | |||||
remove_item(x); | |||||
return *this; | return *this; | ||||
} | } | ||||
@@ -200,21 +200,21 @@ public: | |||||
inline bool push_unique(T const &x) | inline bool push_unique(T const &x) | ||||
{ | { | ||||
if (Find(x) != INDEX_NONE) | |||||
if (find(x) != INDEX_NONE) | |||||
return false; | return false; | ||||
push(x); | push(x); | ||||
return true; | return true; | ||||
} | } | ||||
inline void Insert(T const &x, ptrdiff_t pos) | |||||
inline void insert(T const &x, ptrdiff_t pos) | |||||
{ | { | ||||
ASSERT(pos >= 0 && pos <= m_count, | ASSERT(pos >= 0 && pos <= m_count, | ||||
"cannot insert at index %lld in array of size %lld", | "cannot insert at index %lld in array of size %lld", | ||||
(long long int)pos, (long long int)m_count); | (long long int)pos, (long long int)m_count); | ||||
if (m_count >= m_reserved) | if (m_count >= m_reserved) | ||||
Grow(); | |||||
grow(); | |||||
for (ptrdiff_t i = m_count; i > pos; --i) | for (ptrdiff_t i = m_count; i > pos; --i) | ||||
{ | { | ||||
@@ -225,20 +225,20 @@ public: | |||||
++m_count; | ++m_count; | ||||
} | } | ||||
inline bool InsertUnique(T const &x, ptrdiff_t pos) | |||||
inline bool insert_unique(T const &x, ptrdiff_t pos) | |||||
{ | { | ||||
ASSERT(pos >= 0 && pos <= m_count, | ASSERT(pos >= 0 && pos <= m_count, | ||||
"cannot insert at index %lld in array of size %lld", | "cannot insert at index %lld in array of size %lld", | ||||
(long long int)pos, (long long int)m_count); | (long long int)pos, (long long int)m_count); | ||||
if (Find(x) != INDEX_NONE) | |||||
if (find(x) != INDEX_NONE) | |||||
return false; | return false; | ||||
Insert(x, pos); | |||||
insert(x, pos); | |||||
return true; | return true; | ||||
} | } | ||||
inline ptrdiff_t Find(T const &x) | |||||
inline ptrdiff_t find(T const &x) | |||||
{ | { | ||||
for (ptrdiff_t i = 0; i < m_count; ++i) | for (ptrdiff_t i = 0; i < m_count; ++i) | ||||
if (m_data[i] == x) | if (m_data[i] == x) | ||||
@@ -246,9 +246,9 @@ public: | |||||
return INDEX_NONE; | return INDEX_NONE; | ||||
} | } | ||||
bool RemoveItem(T const &x) | |||||
bool remove_item(T const &x) | |||||
{ | { | ||||
ptrdiff_t idx = Find(x); | |||||
ptrdiff_t idx = find(x); | |||||
if (idx != INDEX_NONE) | if (idx != INDEX_NONE) | ||||
{ | { | ||||
remove(idx); | remove(idx); | ||||
@@ -259,7 +259,7 @@ public: | |||||
bool RemoveSwapItem(T const &x) | bool RemoveSwapItem(T const &x) | ||||
{ | { | ||||
ptrdiff_t idx = Find(x); | |||||
ptrdiff_t idx = find(x); | |||||
if (idx != INDEX_NONE) | if (idx != INDEX_NONE) | ||||
{ | { | ||||
RemoveSwap(idx); | RemoveSwap(idx); | ||||
@@ -270,8 +270,8 @@ public: | |||||
bool SwapItem(T const &x1, T const &x2) | bool SwapItem(T const &x1, T const &x2) | ||||
{ | { | ||||
ptrdiff_t idx1 = Find(x1); | |||||
ptrdiff_t idx2 = Find(x2); | |||||
ptrdiff_t idx1 = find(x1); | |||||
ptrdiff_t idx2 = find(x2); | |||||
if (idx1 != INDEX_NONE && idx2 != INDEX_NONE) | if (idx1 != INDEX_NONE && idx2 != INDEX_NONE) | ||||
{ | { | ||||
swap(idx1, idx2); | swap(idx1, idx2); | ||||
@@ -283,7 +283,7 @@ public: | |||||
inline T pop() | inline T pop() | ||||
{ | { | ||||
ASSERT(m_count > 0); | ASSERT(m_count > 0); | ||||
element_t tmp = Last(); | |||||
element_t tmp = last(); | |||||
remove(m_count - 1, 1); | remove(m_count - 1, 1); | ||||
return tmp; | return tmp; | ||||
} | } | ||||
@@ -339,20 +339,20 @@ public: | |||||
m_count -= todelete; | m_count -= todelete; | ||||
} | } | ||||
void Resize(ptrdiff_t count, element_t e = element_t()) | |||||
void resize(ptrdiff_t item_count, element_t e = element_t()) | |||||
{ | { | ||||
ASSERT(count >= 0); | |||||
Reserve(count); | |||||
ASSERT(item_count >= 0); | |||||
reserve(item_count); | |||||
/* Too many elements? Remove them. */ | /* Too many elements? Remove them. */ | ||||
for (ptrdiff_t i = count; i < m_count; ++i) | |||||
for (ptrdiff_t i = item_count; i < m_count; ++i) | |||||
m_data[i].~element_t(); | m_data[i].~element_t(); | ||||
/* Not enough elements? Add some. */ | /* Not enough elements? Add some. */ | ||||
for (ptrdiff_t i = m_count; i < count; ++i) | |||||
for (ptrdiff_t i = m_count; i < item_count; ++i) | |||||
new(&m_data[i]) element_t(e); | new(&m_data[i]) element_t(e); | ||||
m_count = count; | |||||
m_count = item_count; | |||||
} | } | ||||
inline void empty() | inline void empty() | ||||
@@ -360,7 +360,7 @@ public: | |||||
remove(0, m_count); | remove(0, m_count); | ||||
} | } | ||||
void Reserve(ptrdiff_t toreserve) | |||||
void reserve(ptrdiff_t toreserve) | |||||
{ | { | ||||
if (toreserve <= m_reserved) | if (toreserve <= m_reserved) | ||||
return; | return; | ||||
@@ -393,6 +393,18 @@ public: | |||||
inline void Swap(ptrdiff_t pos1, ptrdiff_t pos2) { return swap(pos1, pos2); } | inline void Swap(ptrdiff_t pos1, ptrdiff_t pos2) { return swap(pos1, pos2); } | ||||
inline void Remove(ptrdiff_t pos, ptrdiff_t todelete = 1) { return remove(pos, todelete); } | inline void Remove(ptrdiff_t pos, ptrdiff_t todelete = 1) { return remove(pos, todelete); } | ||||
inline void Empty() { empty(); } | inline void Empty() { empty(); } | ||||
inline element_t& Last() { return last(); } | |||||
inline element_t *Data() { return data(); } | |||||
inline element_t const *Data() const { return data(); } | |||||
inline element_t const& Last() const { return last(); } | |||||
inline void Insert(T const &x, ptrdiff_t pos) { return insert(x, pos); } | |||||
inline bool InsertUnique(T const &x, ptrdiff_t pos) { return insert_unique(x, pos); } | |||||
inline ptrdiff_t Find(T const &x) { return find(x); } | |||||
inline bool RemoveItem(T const &x) { return remove_item(x); } | |||||
inline void Resize(ptrdiff_t item_count, element_t e = element_t()) { return resize(item_count, e); } | |||||
inline void Reserve(ptrdiff_t toreserve) { return reserve(toreserve); } | |||||
inline ptrdiff_t Count() const { return count(); } | |||||
inline ptrdiff_t Bytes() const { return bytes(); } | |||||
/* Support C++11 range-based for loops */ | /* Support C++11 range-based for loops */ | ||||
class ConstIterator | class ConstIterator | ||||
@@ -454,13 +466,13 @@ public: | |||||
}; | }; | ||||
public: | public: | ||||
inline ptrdiff_t Count() const { return m_count; } | |||||
inline ptrdiff_t Bytes() const { return m_count * sizeof(element_t); } | |||||
inline ptrdiff_t count() const { return m_count; } | |||||
inline ptrdiff_t bytes() const { return m_count * sizeof(element_t); } | |||||
protected: | protected: | ||||
void Grow() | |||||
void grow() | |||||
{ | { | ||||
Reserve(m_count * 13 / 8 + 8); | |||||
reserve(m_count * 13 / 8 + 8); | |||||
} | } | ||||
element_t *m_data; | element_t *m_data; | ||||
@@ -495,7 +507,7 @@ public: | |||||
if (this->m_count >= this->m_reserved) | if (this->m_count >= this->m_reserved) | ||||
{ | { | ||||
tuple<T...> tmp = { args... }; | tuple<T...> tmp = { args... }; | ||||
this->Grow(); | |||||
this->grow(); | |||||
new (&this->m_data[this->m_count].m1) tuple<T...>(tmp); | new (&this->m_data[this->m_count].m1) tuple<T...>(tmp); | ||||
} | } | ||||
else | else | ||||
@@ -512,7 +524,7 @@ public: | |||||
(long long int)pos, (long long int)this->m_count); | (long long int)pos, (long long int)this->m_count); | ||||
if (this->m_count >= this->m_reserved) | if (this->m_count >= this->m_reserved) | ||||
this->Grow(); | |||||
this->grow(); | |||||
for (ptrdiff_t i = this->m_count; i > pos; --i) | for (ptrdiff_t i = this->m_count; i > pos; --i) | ||||
{ | { | ||||
@@ -561,7 +573,7 @@ typename array<T...>::Iterator begin(array<T...> &a) | |||||
template<typename... T> | template<typename... T> | ||||
typename array<T...>::Iterator end(array<T...> &a) | typename array<T...>::Iterator end(array<T...> &a) | ||||
{ | { | ||||
return typename array<T...>::Iterator(&a, a.Count()); | |||||
return typename array<T...>::Iterator(&a, a.count()); | |||||
} | } | ||||
template<typename... T> | template<typename... T> | ||||
@@ -573,7 +585,7 @@ typename array<T...>::ConstIterator begin(array<T...> const &a) | |||||
template<typename... T> | template<typename... T> | ||||
typename array<T...>::ConstIterator end(array<T...> const &a) | typename array<T...>::ConstIterator end(array<T...> const &a) | ||||
{ | { | ||||
return typename array<T...>::ConstIterator(&a, a.Count()); | |||||
return typename array<T...>::ConstIterator(&a, a.count()); | |||||
} | } | ||||
/* | /* | ||||
@@ -1,11 +1,14 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net> | |||||
// © 2013—2015 Benjamin "Touky" Huet <huet.benjamin@gmail.com> | |||||
// | |||||
// This library is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#pragma once | #pragma once | ||||
@@ -28,70 +31,70 @@ namespace lol | |||||
class String : protected array<char> | class String : protected array<char> | ||||
{ | { | ||||
private: | private: | ||||
typedef array<char> Super; | |||||
typedef array<char> super; | |||||
public: | public: | ||||
inline String() | inline String() | ||||
: Super() | |||||
: super() | |||||
{ | { | ||||
Push('\0'); | |||||
push('\0'); | |||||
} | } | ||||
inline String(char const *str) | inline String(char const *str) | ||||
: Super() | |||||
: super() | |||||
{ | { | ||||
using namespace std; | using namespace std; | ||||
ASSERT(str); | ASSERT(str); | ||||
Resize(strlen(str)); | |||||
memcpy(&(*this)[0], str, Count() + 1); | |||||
resize(strlen(str)); | |||||
memcpy(&(*this)[0], str, count() + 1); | |||||
} | } | ||||
inline String(char const *str, ptrdiff_t count) | |||||
: Super() | |||||
inline String(char const *str, ptrdiff_t item_count) | |||||
: super() | |||||
{ | { | ||||
using namespace std; | using namespace std; | ||||
ASSERT(str); | ASSERT(str); | ||||
Resize(count); | |||||
memcpy(&(*this)[0], str, count); | |||||
((Super &)*this)[count] = '\0'; | |||||
resize(item_count); | |||||
memcpy(&(*this)[0], str, item_count); | |||||
((super &)*this)[item_count] = '\0'; | |||||
} | } | ||||
inline String(String const &s) | inline String(String const &s) | ||||
: Super((Super const &)s) | |||||
: super((super const &)s) | |||||
{ | { | ||||
} | } | ||||
inline char &operator [](ptrdiff_t n) | inline char &operator [](ptrdiff_t n) | ||||
{ | { | ||||
/* Allow n == Count() because we might have reasonable reasons | |||||
/* Allow n == count() because we might have reasonable reasons | |||||
* to access that hidden null character. */ | * to access that hidden null character. */ | ||||
ASSERT(n >= 0); | ASSERT(n >= 0); | ||||
ASSERT(n <= Count()); | |||||
return ((Super &)*this)[n]; | |||||
ASSERT(n <= count()); | |||||
return ((super &)*this)[n]; | |||||
} | } | ||||
inline char const &operator [](ptrdiff_t n) const | inline char const &operator [](ptrdiff_t n) const | ||||
{ | { | ||||
ASSERT(n >= 0); | ASSERT(n >= 0); | ||||
ASSERT(n <= Count()); | |||||
return ((Super const &)*this)[n]; | |||||
ASSERT(n <= count()); | |||||
return ((super const &)*this)[n]; | |||||
} | } | ||||
inline char &Last() | |||||
inline char &last() | |||||
{ | { | ||||
ASSERT(Count() > 0); | |||||
return (*this)[Count() - 1]; | |||||
ASSERT(count() > 0); | |||||
return (*this)[count() - 1]; | |||||
} | } | ||||
inline char const &Last() const | |||||
inline char const &last() const | |||||
{ | { | ||||
ASSERT(Count() > 0); | |||||
return (*this)[Count() - 1]; | |||||
ASSERT(count() > 0); | |||||
return (*this)[count() - 1]; | |||||
} | } | ||||
inline ptrdiff_t Count() const | |||||
inline ptrdiff_t count() const | |||||
{ | { | ||||
return ((Super const &)*this).Count() - 1; | |||||
return ((super const &)*this).count() - 1; | |||||
} | } | ||||
/* Return a C string */ | /* Return a C string */ | ||||
@@ -107,24 +110,24 @@ public: | |||||
} | } | ||||
/* Does not initialise the newly allocated characters */ | /* Does not initialise the newly allocated characters */ | ||||
void Resize(ptrdiff_t count) | |||||
void resize(ptrdiff_t item_count) | |||||
{ | { | ||||
ASSERT(count >= 0); | |||||
((Super &)*this).Resize(count + 1); | |||||
((Super &)*this).Last() = '\0'; | |||||
ASSERT(item_count >= 0); | |||||
((super &)*this).resize(item_count + 1); | |||||
((super &)*this).last() = '\0'; | |||||
} | } | ||||
String Sub(ptrdiff_t start, ptrdiff_t count = -1) const | |||||
String sub(ptrdiff_t start, ptrdiff_t item_count = -1) const | |||||
{ | { | ||||
ASSERT(start >= 0); | ASSERT(start >= 0); | ||||
if (start >= Count()) | |||||
if (start >= count()) | |||||
return String(); | return String(); | ||||
if (count < 0 || count >= Count() - start) | |||||
count = Count() - start; | |||||
return String(&(*this)[start], count); | |||||
if (item_count < 0 || item_count >= count() - start) | |||||
item_count = count() - start; | |||||
return String(&(*this)[start], item_count); | |||||
} | } | ||||
ptrdiff_t IndexOf(char token) const | |||||
ptrdiff_t index_of(char token) const | |||||
{ | { | ||||
using namespace std; | using namespace std; | ||||
@@ -132,7 +135,7 @@ public: | |||||
return tmp ? (ptrdiff_t)(tmp - C()) : INDEX_NONE; | return tmp ? (ptrdiff_t)(tmp - C()) : INDEX_NONE; | ||||
} | } | ||||
ptrdiff_t IndexOf(char const* token) const | |||||
ptrdiff_t index_of(char const* token) const | |||||
{ | { | ||||
using namespace std; | using namespace std; | ||||
@@ -140,12 +143,12 @@ public: | |||||
return tmp ? (ptrdiff_t)(tmp - C()) : INDEX_NONE; | return tmp ? (ptrdiff_t)(tmp - C()) : INDEX_NONE; | ||||
} | } | ||||
bool Contains(String const &s) const | |||||
bool contains(String const &s) const | |||||
{ | { | ||||
return IndexOf(s.C()) != INDEX_NONE; | |||||
return index_of(s.C()) != INDEX_NONE; | |||||
} | } | ||||
ptrdiff_t LastIndexOf(char token) const | |||||
ptrdiff_t last_index_of(char token) const | |||||
{ | { | ||||
using namespace std; | using namespace std; | ||||
@@ -153,7 +156,7 @@ public: | |||||
return tmp ? (ptrdiff_t)(tmp - C()) : INDEX_NONE; | return tmp ? (ptrdiff_t)(tmp - C()) : INDEX_NONE; | ||||
} | } | ||||
int Replace(char const old_token, char const new_token, | |||||
int replace(char const old_token, char const new_token, | |||||
bool all_occurrences = false) | bool all_occurrences = false) | ||||
{ | { | ||||
using namespace std; | using namespace std; | ||||
@@ -170,50 +173,51 @@ public: | |||||
return res; | return res; | ||||
} | } | ||||
inline String& ToLower() | |||||
/* FIXME: it doesn't sound safe to apply this in place */ | |||||
inline String& to_lower() | |||||
{ | { | ||||
char* p = C(); | char* p = C(); | ||||
for (ptrdiff_t i = 0; i < Count(); ++i) | |||||
for (ptrdiff_t i = 0; i < count(); ++i) | |||||
if ('A' <= p[i] && p[i] <= 'Z') | if ('A' <= p[i] && p[i] <= 'Z') | ||||
p[i] += 'a' - 'A'; | p[i] += 'a' - 'A'; | ||||
return *this; | return *this; | ||||
} | } | ||||
inline String& ToUpper() | |||||
inline String& to_upper() | |||||
{ | { | ||||
char* p = C(); | char* p = C(); | ||||
for (ptrdiff_t i = 0; i < Count(); ++i) | |||||
for (ptrdiff_t i = 0; i < count(); ++i) | |||||
if ('a' <= p[i] && p[i] <= 'z') | if ('a' <= p[i] && p[i] <= 'z') | ||||
p[i] += 'A' - 'a'; | p[i] += 'A' - 'a'; | ||||
return *this; | return *this; | ||||
} | } | ||||
ptrdiff_t LastIndexOf(char const* token) const | |||||
ptrdiff_t last_index_of(char const* token) const | |||||
{ | { | ||||
using namespace std; | using namespace std; | ||||
ptrdiff_t token_len = strlen(token); | ptrdiff_t token_len = strlen(token); | ||||
for (ptrdiff_t i = Count() - token_len; i >= 0; --i) | |||||
for (ptrdiff_t i = count() - token_len; i >= 0; --i) | |||||
if (strstr(C() + i, token)) | if (strstr(C() + i, token)) | ||||
return i; | return i; | ||||
return -1; | return -1; | ||||
} | } | ||||
bool StartsWith(String const &s) const | |||||
bool starts_with(String const &s) const | |||||
{ | { | ||||
using namespace std; | using namespace std; | ||||
return Count() >= s.Count() | |||||
&& memcmp(C(), s.C(), s.Count()) == 0; | |||||
return count() >= s.count() | |||||
&& memcmp(C(), s.C(), s.count()) == 0; | |||||
} | } | ||||
bool EndsWith(String const &s) const | |||||
bool ends_with(String const &s) const | |||||
{ | { | ||||
using namespace std; | using namespace std; | ||||
return Count() >= s.Count() | |||||
&& memcmp(C() + Count() - s.Count(), s.C(), s.Count()) == 0; | |||||
return count() >= s.count() | |||||
&& memcmp(C() + count() - s.count(), s.C(), s.count()) == 0; | |||||
} | } | ||||
bool IsAlpha() | |||||
bool is_alpha() const | |||||
{ | { | ||||
for (ptrdiff_t i = 0; i < m_count; i++) | for (ptrdiff_t i = 0; i < m_count; i++) | ||||
if (m_data[i] != '\0' && (m_data[i] < '0' || '9' < m_data[i])) | if (m_data[i] != '\0' && (m_data[i] < '0' || '9' < m_data[i])) | ||||
@@ -230,9 +234,9 @@ public: | |||||
inline String& operator +=(String const &s) | inline String& operator +=(String const &s) | ||||
{ | { | ||||
using namespace std; | using namespace std; | ||||
ptrdiff_t old_count = Count(); | |||||
Resize(Count() + s.Count()); | |||||
memcpy(&(*this)[old_count], &s[0], Count() - old_count); | |||||
ptrdiff_t old_count = count(); | |||||
resize(count() + s.count()); | |||||
memcpy(&(*this)[old_count], &s[0], count() - old_count); | |||||
return *this; | return *this; | ||||
} | } | ||||
@@ -244,16 +248,16 @@ public: | |||||
inline String& operator +=(char c) | inline String& operator +=(char c) | ||||
{ | { | ||||
((Super &)*this).Last() = c; | |||||
((Super &)*this).Push('\0'); | |||||
((super &)*this).last() = c; | |||||
((super &)*this).push('\0'); | |||||
return *this; | return *this; | ||||
} | } | ||||
inline bool operator ==(String const &s) const | inline bool operator ==(String const &s) const | ||||
{ | { | ||||
using namespace std; | using namespace std; | ||||
return Count() == s.Count() | |||||
&& memcmp(C(), s.C(), Count()) == 0; | |||||
return count() == s.count() | |||||
&& memcmp(C(), s.C(), count()) == 0; | |||||
} | } | ||||
inline bool operator !=(String const &s) const | inline bool operator !=(String const &s) const | ||||
@@ -267,7 +271,7 @@ public: | |||||
* but it's probably still faster than doing it by hand. */ | * but it's probably still faster than doing it by hand. */ | ||||
using namespace std; | using namespace std; | ||||
ptrdiff_t sz_len = strlen(sz); | ptrdiff_t sz_len = strlen(sz); | ||||
return Count() == sz_len | |||||
return count() == sz_len | |||||
&& memcmp(C(), sz, sz_len) == 0; | && memcmp(C(), sz, sz_len) == 0; | ||||
} | } | ||||
@@ -279,10 +283,10 @@ public: | |||||
inline bool operator <(String const & s) const | inline bool operator <(String const & s) const | ||||
{ | { | ||||
using namespace std; | using namespace std; | ||||
int res = memcmp(C(), s.C(), Count() < s.Count() ? Count() : s.Count()); | |||||
int res = memcmp(C(), s.C(), count() < s.count() ? count() : s.count()); | |||||
if (!res) | if (!res) | ||||
return Count() < s.Count(); | |||||
return count() < s.count(); | |||||
return res < 0; | return res < 0; | ||||
} | } | ||||
@@ -295,6 +299,23 @@ public: | |||||
static String Printf(char const *format, ...) LOL_FMT_ATTR(1, 2); | static String Printf(char const *format, ...) LOL_FMT_ATTR(1, 2); | ||||
#undef LOL_FMT_ATTR | #undef LOL_FMT_ATTR | ||||
static String VPrintf(char const *format, va_list ap); | static String VPrintf(char const *format, va_list ap); | ||||
/* TODO: remove these legacy functions one day */ | |||||
inline char &Last() { return last(); } | |||||
inline char const &Last() const { return last(); } | |||||
inline void Resize(ptrdiff_t item_count) { return resize(item_count); } | |||||
inline String& ToLower() { return to_lower(); } | |||||
inline String& ToUpper() { return to_upper(); } | |||||
inline String Sub(ptrdiff_t start, ptrdiff_t item_count = -1) const { return sub(start, item_count); } | |||||
inline bool Contains(String const &s) const { return contains(s); } | |||||
inline ptrdiff_t IndexOf(char token) const { return index_of(token); } | |||||
inline ptrdiff_t IndexOf(char const* token) const { return index_of(token); } | |||||
inline ptrdiff_t LastIndexOf(char token) const { return last_index_of(token); } | |||||
inline int Replace(char const old_token, char const new_token, bool all_occurrences = false) { return replace(old_token, new_token, all_occurrences); } | |||||
inline bool EndsWith(String const &s) const { return ends_with(s); } | |||||
inline bool IsAlpha() const { return is_alpha(); } | |||||
inline bool StartsWith(String const &s) const { return starts_with(s); } | |||||
inline ptrdiff_t Count() const { return count(); } | |||||
}; | }; | ||||
inline bool operator ==(char const* sz, String const &s) | inline bool operator ==(char const* sz, String const &s) | ||||
@@ -1,11 +1,14 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net> | |||||
// © 2014—2015 Benjamin "Touky" Huet <huet.benjamin@gmail.com> | |||||
// | |||||
// This program is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -15,34 +18,34 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
lolunit_declare_fixture(StringTest) | |||||
lolunit_declare_fixture(string_test) | |||||
{ | { | ||||
void SetUp() {} | void SetUp() {} | ||||
void TearDown() {} | void TearDown() {} | ||||
lolunit_declare_test(StringBuild) | |||||
lolunit_declare_test(string_build) | |||||
{ | { | ||||
String s1; | String s1; | ||||
lolunit_assert_equal(s1.Count(), 0); | |||||
lolunit_assert_equal(s1.count(), 0); | |||||
lolunit_assert_equal(s1[0], '\0'); | lolunit_assert_equal(s1[0], '\0'); | ||||
String s2(""); | String s2(""); | ||||
lolunit_assert_equal(s2.Count(), 0); | |||||
lolunit_assert_equal(s2.count(), 0); | |||||
lolunit_assert_equal(s2[0], '\0'); | lolunit_assert_equal(s2[0], '\0'); | ||||
String s3("a"); | String s3("a"); | ||||
lolunit_assert_equal(s3.Count(), 1); | |||||
lolunit_assert_equal(s3.count(), 1); | |||||
lolunit_assert_equal(s3[0], 'a'); | lolunit_assert_equal(s3[0], 'a'); | ||||
lolunit_assert_equal(s3[1], '\0'); | lolunit_assert_equal(s3[1], '\0'); | ||||
String s4(s3); | String s4(s3); | ||||
lolunit_assert_equal(s4.Count(), 1); | |||||
lolunit_assert_equal(s4.count(), 1); | |||||
lolunit_assert_equal(s4[0], 'a'); | lolunit_assert_equal(s4[0], 'a'); | ||||
lolunit_assert_equal(s4[1], '\0'); | lolunit_assert_equal(s4[1], '\0'); | ||||
} | } | ||||
lolunit_declare_test(StringAppendChar) | |||||
lolunit_declare_test(string_append_char) | |||||
{ | { | ||||
String s; | String s; | ||||
s += 'a'; | s += 'a'; | ||||
@@ -55,7 +58,7 @@ lolunit_declare_fixture(StringTest) | |||||
lolunit_assert_equal(s[3], '\0'); | lolunit_assert_equal(s[3], '\0'); | ||||
} | } | ||||
lolunit_declare_test(StringCopy) | |||||
lolunit_declare_test(string_copy) | |||||
{ | { | ||||
String s1 = "abc"; | String s1 = "abc"; | ||||
@@ -67,7 +70,7 @@ lolunit_declare_fixture(StringTest) | |||||
lolunit_assert_equal(s1[3], s2[3]); | lolunit_assert_equal(s1[3], s2[3]); | ||||
} | } | ||||
lolunit_declare_test(StringConcat) | |||||
lolunit_declare_test(string_concat) | |||||
{ | { | ||||
String s1("ab"), s2("cd"); | String s1("ab"), s2("cd"); | ||||
@@ -79,12 +82,12 @@ lolunit_declare_fixture(StringTest) | |||||
lolunit_assert_equal(s3[4], '\0'); | lolunit_assert_equal(s3[4], '\0'); | ||||
} | } | ||||
lolunit_declare_test(StringAppendString) | |||||
lolunit_declare_test(string_append_string) | |||||
{ | { | ||||
String s1("ab"), s2("cd"); | String s1("ab"), s2("cd"); | ||||
s1 += s2; | s1 += s2; | ||||
lolunit_assert_equal(s1.Count(), 4); | |||||
lolunit_assert_equal(s1.count(), 4); | |||||
lolunit_assert_equal(s1[0], 'a'); | lolunit_assert_equal(s1[0], 'a'); | ||||
lolunit_assert_equal(s1[1], 'b'); | lolunit_assert_equal(s1[1], 'b'); | ||||
lolunit_assert_equal(s1[2], 'c'); | lolunit_assert_equal(s1[2], 'c'); | ||||
@@ -92,7 +95,7 @@ lolunit_declare_fixture(StringTest) | |||||
lolunit_assert_equal(s1[4], '\0'); | lolunit_assert_equal(s1[4], '\0'); | ||||
s2 += s2; | s2 += s2; | ||||
lolunit_assert_equal(s2.Count(), 4); | |||||
lolunit_assert_equal(s2.count(), 4); | |||||
lolunit_assert_equal(s2[0], 'c'); | lolunit_assert_equal(s2[0], 'c'); | ||||
lolunit_assert_equal(s2[1], 'd'); | lolunit_assert_equal(s2[1], 'd'); | ||||
lolunit_assert_equal(s2[2], 'c'); | lolunit_assert_equal(s2[2], 'c'); | ||||
@@ -100,7 +103,7 @@ lolunit_declare_fixture(StringTest) | |||||
lolunit_assert_equal(s2[4], '\0'); | lolunit_assert_equal(s2[4], '\0'); | ||||
} | } | ||||
lolunit_declare_test(StringEqual) | |||||
lolunit_declare_test(string_equal) | |||||
{ | { | ||||
String s1("abc"); | String s1("abc"); | ||||
String s2("abc"); | String s2("abc"); | ||||
@@ -110,7 +113,7 @@ lolunit_declare_fixture(StringTest) | |||||
lolunit_assert(!(s1 == s3)); | lolunit_assert(!(s1 == s3)); | ||||
} | } | ||||
lolunit_declare_test(StringDifferent) | |||||
lolunit_declare_test(string_different) | |||||
{ | { | ||||
String s1("abc"); | String s1("abc"); | ||||
String s2("ab"); | String s2("ab"); | ||||
@@ -120,7 +123,7 @@ lolunit_declare_fixture(StringTest) | |||||
lolunit_assert(!(s1 != s3)); | lolunit_assert(!(s1 != s3)); | ||||
} | } | ||||
lolunit_declare_test(StringCharsEqual) | |||||
lolunit_declare_test(string_chars_equal) | |||||
{ | { | ||||
char const* sz = "abc"; | char const* sz = "abc"; | ||||
String s1("abc"); | String s1("abc"); | ||||
@@ -132,7 +135,7 @@ lolunit_declare_fixture(StringTest) | |||||
lolunit_assert(!(sz == s2)); | lolunit_assert(!(sz == s2)); | ||||
} | } | ||||
lolunit_declare_test(StringCharsDifferent) | |||||
lolunit_declare_test(string_chars_different) | |||||
{ | { | ||||
char const* sz = "abc"; | char const* sz = "abc"; | ||||
String s1("ab"); | String s1("ab"); | ||||
@@ -145,7 +148,7 @@ lolunit_declare_fixture(StringTest) | |||||
} | } | ||||
lolunit_declare_test(StringPrintf) | |||||
lolunit_declare_test(string_printf) | |||||
{ | { | ||||
String s1 = "3a"; | String s1 = "3a"; | ||||
String s2 = String::Printf("%d%x", 3, 10); | String s2 = String::Printf("%d%x", 3, 10); | ||||
@@ -158,30 +161,30 @@ lolunit_declare_fixture(StringTest) | |||||
lolunit_assert(s3 == s4); | lolunit_assert(s3 == s4); | ||||
} | } | ||||
lolunit_declare_test(SubString) | |||||
lolunit_declare_test(substring) | |||||
{ | { | ||||
String s1 = "Hello World"; | String s1 = "Hello World"; | ||||
String s2 = s1.Sub(0, 5); | |||||
String s2 = s1.sub(0, 5); | |||||
String s3 = "Hello"; | String s3 = "Hello"; | ||||
lolunit_assert(s2 == s3); | lolunit_assert(s2 == s3); | ||||
String s4 = s1.Sub(6, 5); | |||||
String s4 = s1.sub(6, 5); | |||||
String s5 = "World"; | String s5 = "World"; | ||||
lolunit_assert(s4 == s5); | lolunit_assert(s4 == s5); | ||||
} | } | ||||
lolunit_declare_test(IndexOf) | |||||
lolunit_declare_test(index_of) | |||||
{ | { | ||||
String s1 = "Hello World"; | String s1 = "Hello World"; | ||||
ptrdiff_t i1 = s1.IndexOf('H'); | |||||
ptrdiff_t i2 = s1.IndexOf('W'); | |||||
ptrdiff_t i3 = s1.IndexOf('d'); | |||||
ptrdiff_t i4 = s1.IndexOf("Hello"); | |||||
ptrdiff_t i5 = s1.IndexOf("World"); | |||||
ptrdiff_t i6 = s1.IndexOf("lo"); | |||||
ptrdiff_t i7 = s1.IndexOf("Hello World"); | |||||
ptrdiff_t i8 = s1.IndexOf("Sup' dude"); | |||||
ptrdiff_t i1 = s1.index_of('H'); | |||||
ptrdiff_t i2 = s1.index_of('W'); | |||||
ptrdiff_t i3 = s1.index_of('d'); | |||||
ptrdiff_t i4 = s1.index_of("Hello"); | |||||
ptrdiff_t i5 = s1.index_of("World"); | |||||
ptrdiff_t i6 = s1.index_of("lo"); | |||||
ptrdiff_t i7 = s1.index_of("Hello World"); | |||||
ptrdiff_t i8 = s1.index_of("Sup' dude"); | |||||
lolunit_assert(i1 == 0); | lolunit_assert(i1 == 0); | ||||
lolunit_assert(i2 == 6); | lolunit_assert(i2 == 6); | ||||
@@ -193,18 +196,18 @@ lolunit_declare_fixture(StringTest) | |||||
lolunit_assert(i8 == -1); | lolunit_assert(i8 == -1); | ||||
} | } | ||||
lolunit_declare_test(LastIndexOf) | |||||
lolunit_declare_test(last_index_of) | |||||
{ | { | ||||
String s1 = "Hello World"; | String s1 = "Hello World"; | ||||
ptrdiff_t i1 = s1.LastIndexOf('H'); | |||||
ptrdiff_t i2 = s1.LastIndexOf('W'); | |||||
ptrdiff_t i3 = s1.LastIndexOf('d'); | |||||
ptrdiff_t i4 = s1.LastIndexOf("Hello"); | |||||
ptrdiff_t i5 = s1.LastIndexOf("World"); | |||||
ptrdiff_t i6 = s1.LastIndexOf("lo"); | |||||
ptrdiff_t i7 = s1.LastIndexOf("Hello World"); | |||||
ptrdiff_t i8 = s1.LastIndexOf("Sup' dude"); | |||||
ptrdiff_t i9 = s1.LastIndexOf('l'); | |||||
ptrdiff_t i1 = s1.last_index_of('H'); | |||||
ptrdiff_t i2 = s1.last_index_of('W'); | |||||
ptrdiff_t i3 = s1.last_index_of('d'); | |||||
ptrdiff_t i4 = s1.last_index_of("Hello"); | |||||
ptrdiff_t i5 = s1.last_index_of("World"); | |||||
ptrdiff_t i6 = s1.last_index_of("lo"); | |||||
ptrdiff_t i7 = s1.last_index_of("Hello World"); | |||||
ptrdiff_t i8 = s1.last_index_of("Sup' dude"); | |||||
ptrdiff_t i9 = s1.last_index_of('l'); | |||||
lolunit_assert(i1 == 0); | lolunit_assert(i1 == 0); | ||||
lolunit_assert(i2 == 6); | lolunit_assert(i2 == 6); | ||||
@@ -217,18 +220,18 @@ lolunit_declare_fixture(StringTest) | |||||
lolunit_assert(i9 == 9); | lolunit_assert(i9 == 9); | ||||
} | } | ||||
lolunit_declare_test(StartsEndsWith) | |||||
lolunit_declare_test(starts_ends_with) | |||||
{ | { | ||||
String s = "lolilol"; | String s = "lolilol"; | ||||
lolunit_assert(s.StartsWith("loli")); | |||||
lolunit_assert(!s.StartsWith("lolo")); | |||||
lolunit_assert(!s.StartsWith("lolilolilol")); | |||||
lolunit_assert(s.EndsWith("ilol")); | |||||
lolunit_assert(!s.EndsWith("olol")); | |||||
lolunit_assert(!s.EndsWith("lolilolilol")); | |||||
lolunit_assert(s.starts_with("loli")); | |||||
lolunit_assert(!s.starts_with("lolo")); | |||||
lolunit_assert(!s.starts_with("lolilolilol")); | |||||
lolunit_assert(s.ends_with("ilol")); | |||||
lolunit_assert(!s.ends_with("olol")); | |||||
lolunit_assert(!s.ends_with("lolilolilol")); | |||||
} | } | ||||
lolunit_declare_test(StringCompare) | |||||
lolunit_declare_test(string_compare) | |||||
{ | { | ||||
String s1 = "lolilol"; | String s1 = "lolilol"; | ||||
String s2 = s1; | String s2 = s1; | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// This library is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -80,7 +82,7 @@ void Text::TickDraw(float seconds, Scene &scene) | |||||
{ | { | ||||
Entity::TickDraw(seconds, scene); | Entity::TickDraw(seconds, scene); | ||||
int length = data->m_text.Count(); | |||||
int length = data->m_text.count(); | |||||
if (length) | if (length) | ||||
{ | { | ||||
Font *font = Forge::GetFont(data->font); | Font *font = Forge::GetFont(data->font); | ||||
@@ -1,12 +1,14 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2012-2013 Benjamin "Touky" Huet <huet.benjamin@gmail.com> | |||||
// (c) 2012-2013 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net> | |||||
// © 2012—2015 Benjamin "Touky" Huet <huet.benjamin@gmail.com> | |||||
// | |||||
// This library is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#pragma once | #pragma once | ||||
@@ -62,10 +64,10 @@ template< class T > inline int GetRandom(array<T> src) | |||||
template<class T> inline T FindValue(const char* name) | template<class T> inline T FindValue(const char* name) | ||||
{ | { | ||||
String n = name; | String n = name; | ||||
n.ToLower(); | |||||
n.to_lower(); | |||||
for (int i = 0; i < T::Max; ++i) | for (int i = 0; i < T::Max; ++i) | ||||
{ | { | ||||
String s = T(i).ToString().ToLower(); | |||||
String s = T(i).ToString().to_lower(); | |||||
if (s == n) | if (s == n) | ||||
return T(i); | return T(i); | ||||
} | } | ||||