Skip to content

Commit 426ba57

Browse files
committed
WASM support
1 parent 091a1b6 commit 426ba57

File tree

5 files changed

+82
-74
lines changed

5 files changed

+82
-74
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ file(GLOB_RECURSE
3030
)
3131

3232
# Build and install Flow library
33-
add_library(LangulusFlow ${LANGULUS_LIBRARY_TYPE}
33+
add_langulus_library(LangulusFlow
3434
$<TARGET_OBJECTS:LangulusLogger>
3535
$<TARGET_OBJECTS:LangulusRTTI>
3636
$<$<BOOL:${LANGULUS_FEATURE_MANAGED_MEMORY}>:$<TARGET_OBJECTS:LangulusFractalloc>>

source/Code.cpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
#include "verbs/Greater.inl"
2525
#include "verbs/GreaterOrEqual.inl"
2626

27+
#if LANGULUS_COMPILER(WASM)
28+
#include <string>
29+
#endif
30+
2731
LANGULUS_RTTI_BOUNDARY(RTTI::MainBoundary)
2832

2933
#define ENABLE_VERBOSE() 0
@@ -469,10 +473,21 @@ namespace Langulus::Flow
469473
Offset progress = 0;
470474
VERBOSE_TAB("Parsing number");
471475

472-
if (auto [p, ec] = ::std::from_chars(input.GetRaw(), input.GetRaw() + input.GetCount(), rhs);
476+
#if LANGULUS_COMPILER(WASM)
477+
// Some standard library implementations don't allow for
478+
// from_chars that involve parsing float/double
479+
if constexpr (CT::Float<Real>)
480+
rhs = ::std::stof(std::string(Token(input.GetRaw(), input.GetRaw() + input.GetCount())));
481+
else if constexpr (CT::Double<Real>)
482+
rhs = ::std::stod(std::string(Token(input.GetRaw(), input.GetRaw() + input.GetCount())));
483+
484+
static_assert(CT::Float<Real> or CT::Double<Real>, "Unsupported real number type");
485+
#else
486+
if (auto [p, ec] = ::std::from_chars(input.GetRaw(), input.GetRaw() + input.GetCount(), rhs);
473487
ec == ::std::errc()) {
474488
progress = p - input.GetRaw();
475489
}
490+
#endif
476491

477492
VERBOSE(Logger::Green, "Number parsed: ", rhs);
478493
lhs << rhs;

source/Code.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ namespace Langulus::Flow
172172
namespace Langulus
173173
{
174174
/// Convenience operator for code string literals
175-
Flow::Code operator "" _code(const char*, ::std::size_t);
175+
Flow::Code operator ""_code(const char*, ::std::size_t);
176176
}
177177

178178
LANGULUS_DEFINE_CONSTANT(Yes, true, "Yes", "The true boolean value");

source/Code.inl

+2-2
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,13 @@ namespace Langulus
120120

121121
/// Make a code literal
122122
LANGULUS(INLINED)
123-
Flow::Code operator "" _code(const char* text, ::std::size_t size) {
123+
Flow::Code operator ""_code(const char* text, ::std::size_t size) {
124124
return Anyness::Text::From(text, size);
125125
}
126126

127127
/// Make a code literal and parse it
128128
LANGULUS(INLINED)
129-
auto operator "" _parse(const char* text, ::std::size_t size) {
129+
auto operator ""_parse(const char* text, ::std::size_t size) {
130130
return Flow::Code(Anyness::Text::From(text, size)).Parse();
131131
}
132132

source/verbs/Catenate.inl

+62-69
Original file line numberDiff line numberDiff line change
@@ -13,76 +13,69 @@
1313
namespace Langulus
1414
{
1515

16-
/// Number of digits in a value
16+
/// Count digits in real numbers
17+
/// The dot in the real number is considered a digit, too
1718
/// Credit goes to http://stackoverflow.com/questions/1489830
18-
NOD() constexpr LANGULUS(INLINED) Count CountDigits(uint8_t x) noexcept {
19-
return (x < 10u ? 1 : (x < 100u ? 2 : 3));
20-
}
21-
22-
NOD() constexpr LANGULUS(INLINED) Count CountDigits(int8_t x) noexcept {
23-
return CountDigits(static_cast<uint8_t>(::std::abs(x)));
24-
}
25-
26-
NOD() constexpr LANGULUS(INLINED) Count CountDigits(uint16_t x) noexcept {
27-
return (x < 10u ? 1 : (x < 100u ? 2 : (x < 1000u ? 3 : (x < 10000u ? 4 : 5))));
28-
}
29-
30-
NOD() constexpr LANGULUS(INLINED) Count CountDigits(int16_t x) noexcept {
31-
return CountDigits(static_cast<uint16_t>(::std::abs(x)));
32-
}
33-
34-
NOD() constexpr LANGULUS(INLINED) Count CountDigits(uint32_t x) noexcept {
35-
return
36-
(x < 10u ? 1 :
37-
(x < 100u ? 2 :
38-
(x < 1000u ? 3 :
39-
(x < 10000u ? 4 :
40-
(x < 100000u ? 5 :
41-
(x < 1000000u ? 6 :
42-
(x < 10000000u ? 7 :
43-
(x < 100000000u ? 8 :
44-
(x < 1000000000u ? 9 : 10)))))))));
45-
}
46-
47-
NOD() constexpr LANGULUS(INLINED) Count pcNumDigits(int32_t x) noexcept {
48-
return CountDigits(static_cast<uint32_t>(::std::abs(x)));
49-
}
50-
51-
NOD() constexpr LANGULUS(INLINED) Count CountDigits(uint64_t x) noexcept {
52-
return
53-
(x < 10ull ? 1 :
54-
(x < 100ull ? 2 :
55-
(x < 1000ull ? 3 :
56-
(x < 10000ull ? 4 :
57-
(x < 100000ull ? 5 :
58-
(x < 1000000ull ? 6 :
59-
(x < 10000000ull ? 7 :
60-
(x < 100000000ull ? 8 :
61-
(x < 1000000000ull ? 9 :
62-
(x < 10000000000ull ? 10 :
63-
(x < 100000000000ull ? 11 :
64-
(x < 1000000000000ull ? 12 :
65-
(x < 10000000000000ull ? 13 :
66-
(x < 100000000000000ull ? 14 :
67-
(x < 1000000000000000ull ? 15 :
68-
(x < 10000000000000000ull ? 16 :
69-
(x < 100000000000000000ull ? 17 :
70-
(x < 1000000000000000000ull ? 18 :
71-
(x < 10000000000000000000ull ? 19 : 20
72-
)))))))))))))))))));
73-
}
74-
75-
NOD() constexpr LANGULUS(INLINED) Count CountDigits(int64_t x) noexcept {
76-
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs
77-
int const mask = x >> (sizeof(int64_t) * 8 - 1);
78-
return CountDigits(static_cast<uint64_t>((x + mask) ^ mask));
19+
/// @param x - real number to count digits of
20+
template<CT::Integer T> NOD() LANGULUS(INLINED)
21+
constexpr Count CountDigits(T x) noexcept {
22+
if constexpr (CT::UnsignedInteger8<T>)
23+
return (x < 10u ? 1 : (x < 100u ? 2 : 3));
24+
else if constexpr (CT::SignedInteger8<T>)
25+
return CountDigits(static_cast<uint8_t>(::std::abs(x)));
26+
else if constexpr (CT::UnsignedInteger16<T>)
27+
return (x < 10u ? 1 : (x < 100u ? 2 : (x < 1000u ? 3 : (x < 10000u ? 4 : 5))));
28+
else if constexpr (CT::SignedInteger16<T>)
29+
return CountDigits(static_cast<uint16_t>(::std::abs(x)));
30+
else if constexpr (CT::UnsignedInteger32<T>) {
31+
return
32+
(x < 10u ? 1 :
33+
(x < 100u ? 2 :
34+
(x < 1000u ? 3 :
35+
(x < 10000u ? 4 :
36+
(x < 100000u ? 5 :
37+
(x < 1000000u ? 6 :
38+
(x < 10000000u ? 7 :
39+
(x < 100000000u ? 8 :
40+
(x < 1000000000u ? 9 : 10)))))))));
41+
}
42+
else if constexpr (CT::SignedInteger32<T>)
43+
return CountDigits(static_cast<uint32_t>(::std::abs(x)));
44+
else if constexpr (CT::UnsignedInteger64<T>) {
45+
return
46+
(x < 10ull ? 1 :
47+
(x < 100ull ? 2 :
48+
(x < 1000ull ? 3 :
49+
(x < 10000ull ? 4 :
50+
(x < 100000ull ? 5 :
51+
(x < 1000000ull ? 6 :
52+
(x < 10000000ull ? 7 :
53+
(x < 100000000ull ? 8 :
54+
(x < 1000000000ull ? 9 :
55+
(x < 10000000000ull ? 10 :
56+
(x < 100000000000ull ? 11 :
57+
(x < 1000000000000ull ? 12 :
58+
(x < 10000000000000ull ? 13 :
59+
(x < 100000000000000ull ? 14 :
60+
(x < 1000000000000000ull ? 15 :
61+
(x < 10000000000000000ull ? 16 :
62+
(x < 100000000000000000ull ? 17 :
63+
(x < 1000000000000000000ull ? 18 :
64+
(x < 10000000000000000000ull ? 19 : 20
65+
)))))))))))))))))));
66+
}
67+
else if constexpr (CT::SignedInteger64<T>) {
68+
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs
69+
int const mask = x >> (sizeof(int64_t) * 8 - 1);
70+
return CountDigits(static_cast<uint64_t>((x + mask) ^ mask));
71+
}
72+
else static_assert(false, "Unimplemented integer");
7973
}
8074

81-
/// Count digits in real numbers
82-
/// The dot in the real number is considered a digit, too
83-
/// @param x - real number to cound digits of
84-
template<CT::Real T>
85-
NOD() constexpr LANGULUS(INLINED) Count CountDigits(T x) noexcept {
75+
/// Count digits in integer numbers
76+
/// @param x - integer number to count digits of
77+
template<CT::Real T> NOD() LANGULUS(INLINED)
78+
constexpr Count CountDigits(T x) noexcept {
8679
T floored;
8780
T fraction {::std::abs(::std::modf(x, &floored))};
8881
if (fraction == 0)
@@ -104,8 +97,8 @@ namespace Langulus
10497
/// @param lhs - left number
10598
/// @param rhs - right number
10699
/// @return the concatenation of the two numbers
107-
template<CT::Number T>
108-
NOD() LANGULUS(INLINED) T ConcatenateNumbers(const T& lhs, const T& rhs) {
100+
template<CT::Number T> NOD() LANGULUS(INLINED)
101+
T ConcatenateNumbers(const T& lhs, const T& rhs) {
109102
T result {lhs};
110103
result *= ::std::pow(T {10}, static_cast<T>(CountDigits(rhs)));
111104
result += rhs;

0 commit comments

Comments
 (0)