21. Useful Functions
Learn about several small functions that make Siv3D programming more convenient.
21.1 Minimum and Maximum Values
Min(a, b)
returns the smaller of a
and b
Max(a, b)
returns the larger of a
and b
- Both arguments must be of the same type
- If the arguments are of different types, explicitly specify the type like
Min<size_t>(a, b)
# include <Siv3D.hpp>
void Main()
{
Print << Min(10, 20);
Print << Max(10, 20);
Print << Min(12.3, 45.6);
Print << Max(12.3, 45.6);
String s = U"Hello";
Print << Min<size_t>(s.size(), 4);
Print << Max<size_t>(s.size(), 4);
while (System::Update())
{
}
}
Output10
20
12.3
45.6
4
5
21.2 Clamping to a Range
Clamp(value, min, max)
returns value
clamped to the range [min, max]
Clamp(-20, 0, 100)
returns 0
Clamp(50, 0, 100)
returns 50
Clamp(120, 0, 100)
returns 100
- All three arguments must be of the same type
# include <Siv3D.hpp>
void Main()
{
Print << Clamp(-20, 0, 100);
Print << Clamp(50, 0, 100);
Print << Clamp(120, 0, 100);
while (System::Update())
{
}
}
21.3 Checking if in Range
InRange(value, min, max)
returns a bool
indicating whether value
is within the range [min, max]
InRange(50, 0, 100)
returns true
InRange(120, 0, 100)
returns false
# include <Siv3D.hpp>
void Main()
{
Print << InRange(50, 0, 100);
Print << InRange(120, 0, 100);
while (System::Update())
{
}
}
21.4 Checking Odd and Even Numbers
IsOdd(n)
returns a bool
indicating whether the integer n
is odd
IsEven(n)
returns a bool
indicating whether the integer n
is even
# include <Siv3D.hpp>
void Main()
{
Print << IsOdd(3);
Print << IsOdd(4);
Print << IsEven(3);
Print << IsEven(4);
while (System::Update())
{
}
}
Outputtrue
false
false
true
21.5 Absolute Value
Abs(value)
returns the absolute value of value
Abs(-10)
returns 10
Abs(10)
returns 10
Abs(-3.14)
returns 3.14
Abs(3.14)
returns 3.14
# include <Siv3D.hpp>
void Main()
{
Print << Abs(-10);
Print << Abs(10);
Print << Abs(-3.14);
Print << Abs(3.14);
while (System::Update())
{
}
}
21.6 Absolute Difference
AbsDiff(a, b)
returns the absolute difference between a
and b
AbsDiff(10, 20)
returns 10
AbsDiff(20, 10)
returns 10
AbsDiff(3.14, 2.71)
returns 0.43
AbsDiff(2.71, 3.14)
returns 0.43
# include <Siv3D.hpp>
void Main()
{
Print << AbsDiff(10, 20);
Print << AbsDiff(20, 10);
Print << AbsDiff(3.14, 2.71);
Print << AbsDiff(2.71, 3.14);
while (System::Update())
{
}
}
21.7 Indexed Range-based for Loop
- In range-based for loops, you can use
Indexed()
to handle both integer indices and elements of the range simultaneously
# include <Siv3D.hpp>
void Main()
{
const Array<String> animals = { U"cat", U"dog", U"bird" };
for (auto&& [i, animal] : Indexed(animals))
{
Print << U"{}: {}"_fmt(i, animal);
}
while (System::Update())
{
}
}
Output0: cat
1: dog
2: bird
21.8 Indexed Range-based for Loop (Reference)
- To get each element by reference in an indexed range-based for loop, use
IndexedRef()
# include <Siv3D.hpp>
void Main()
{
Array<int32> numbers = { 10, 20, 30 };
for (auto&& [i, number] : IndexedRef(numbers))
{
number += i;
}
for (const auto& number : numbers)
{
Print << number;
}
while (System::Update())
{
}
}
21.9 Loop Shorthand
- You can write
for (int32 i = 0; i < N; ++i)
more concisely as for (auto i : step(N))
- You can write
for (auto i = from; i <= to; ++i)
more concisely as for (auto i : Range(from, to))
# include <Siv3D.hpp>
void Main()
{
for (auto i : step(3))
{
Print << i;
}
Print << U"---";
for (auto i : Range(5, 10))
{
Print << i;
}
while (System::Update())
{
}
}
Output0
1
2
---
5
6
7
8
9
10
21.10 Checking Character Properties
- There are functions to check properties of characters (mainly ASCII characters)
Function |
Description |
bool IsASCII(char32) |
Returns whether the character is an ASCII character |
bool IsDigit(char32) |
Returns whether the character is a decimal digit |
bool IsLower(char32) |
Returns whether the character is a lowercase letter |
bool IsUpper(char32) |
Returns whether the character is an uppercase letter |
bool IsAlpha(char32) |
Returns whether the character is an alphabetic letter |
bool IsAlnum(char32) |
Returns whether the character is alphabetic or numeric |
bool IsXdigit(char32) |
Returns whether the character is a hexadecimal digit |
bool IsControl(char32) |
Returns whether the character is a control character |
bool IsBlank(char32) |
Returns whether the character is a blank character (' ' , '\t' , and full-width space) |
bool IsSpace(char32) |
Returns whether the character is a whitespace character (' ' , '\t' , '\n' , '\v' , '\f' , '\r' , and full-width space) |
bool IsPrint(char32) |
Returns whether the character is a printable character |
char32 ToLower(char32) |
Converts an uppercase letter to lowercase |
char32 ToUpper(char32) |
Converts a lowercase letter to uppercase |
# include <Siv3D.hpp>
void Main()
{
Print << IsASCII(U'A') << U' ' << IsASCII(U'あ');
Print << IsUpper(U'A') << U' ' << IsUpper(U'a');
Print << IsAlnum(U'4') << U' ' << IsAlnum(U'#');
Print << IsSpace(U' ') << U' ' << IsSpace(U'-');
Print << ToLower(U'A') << U' ' << ToLower(U'a');
while (System::Update())
{
}
}
Outputtrue false
true false
true false
true false
a a
21.11 Mathematical Constants
- The following mathematical constants are available
# include <Siv3D.hpp>
void Main()
{
// Pi
Print << Math::Pi;
// Golden ratio
Print << Math::Phi;
// NaN
Print << Math::QNaN;
while (System::Update())
{
}
}
Output3.14159
1.61803
nan
21.12 Angle Representation
- While C++ and Siv3D APIs handle angles in radians, you can use different units for notation for better readability
- Using the
_deg
suffix, you can express angles in degrees
- For example,
90_deg
becomes (90 * Math::Pi / 180.0)
, which is 90° expressed in radians
- Using the
_pi
suffix, you can omit multiplication with π
- For example,
0.5_pi
is the same as (0.5 * Math::Pi)
- You can express angles using the constant τ, which is defined as the ratio of a circle's circumference to its radius. The suffix is
_tau
- For example,
0.5_tau
is the same as (0.5 * Math::TwoPi)
, which is 180° expressed in radians
Suffix |
Description |
Value multiplied to the number |
_deg |
Degrees |
Math::Pi / 180.0 |
_pi |
π |
Math::Pi |
_tau |
τ |
Math::TwoPi |
# include <Siv3D.hpp>
void Main()
{
Print << U"{}"_fmt(180_deg);
Print << U"{}"_fmt(1_pi);
Print << U"{}"_fmt(0.5_tau);
while (System::Update())
{
}
}
Output3.141592653589793
3.141592653589793
3.141592653589793
21.13 Angle Normalization
- To normalize an angle (in radians), use
Math::NormalizeAngle(radian, center = Pi)
- The second argument is the center angle for normalization. If omitted,
Pi
is used
- When the center angle is Pi, the return value range is
[0, 2π)
- When the center angle is 0, the return value range is
[-π, π)
# include <Siv3D.hpp>
void Main()
{
while (System::Update())
{
const double a = (Scene::Time() * -90_deg);
const double b = (Scene::Time() * 90_deg);
ClearPrint();
Print << a;
// Returns the angle normalized to the range [0.0, 2π)
Print << Math::NormalizeAngle(a);
// Returns the angle normalized to the range [-π, π)
Print << Math::NormalizeAngle(a, 0.0);
Print << U"----";
Print << b;
// Returns the angle normalized to the range [0.0, 2π)
Print << Math::NormalizeAngle(b);
// Returns the angle normalized to the range [-π, π)
Print << Math::NormalizeAngle(b, 0.0);
}
}
Example Output-3.86462
2.41857
2.41857
----
3.86462
3.86462
-2.41857
21.14 Converting Between Radians and Degrees
- To convert from radians to degrees, use
Math::ToDegrees(radian)
- To convert from degrees to radians, use
Math::ToRadians(degrees)
# include <Siv3D.hpp>
void Main()
{
const double angle = 45_deg;
Print << angle;
Print << Math::ToDegrees(angle);
Print << Math::ToRadians(Math::ToDegrees(angle));
while (System::Update())
{
}
}
21.15 Converting from Enum to Integer
- Use
FromEnum(enum)
to convert an enum value to an integer
# include <Siv3D.hpp>
enum class State
{
Menu,
Game,
Result
};
void Main()
{
State state = State::Result;
const int32 n = FromEnum(state);
Print << n;
while (System::Update())
{
}
}
21.16 Converting from Integer to Enum
- Use
ToEnum<Enum>(i)
to convert an integer to an enum
# include <Siv3D.hpp>
enum class State
{
Menu,
Game,
Result
};
void Main()
{
const int32 n = 2;
State state = ToEnum<State>(n);
Print << (state == State::Result);
while (System::Update())
{
}
}
21.17 Errors
- When you want to throw an exception to report an error in a Siv3D program, the
Error
class is convenient
- If this exception is not caught, the Siv3D engine will display the error message content in a message box and terminate the program
- For displaying the exception location in the IDE on Windows (Visual Studio), see Displaying Exception Locations
# include <Siv3D.hpp>
void Main()
{
const Texture texture{ U"aaa.png" };
if (not texture)
{
// Throw an exception
throw Error{ U"Failed to load `aaa.png`" };
}
while (System::Update())
{
}
}
21.18 Getting Command Line Arguments
- To get command line arguments passed when the program starts, use
System::GetCommandLineArgs()
# include <Siv3D.hpp>
void Main()
{
const Array<String> commands = System::GetCommandLineArgs();
for (const auto& command : commands)
{
Print << command;
}
while (System::Update())
{
}
}
21.19 Console Output
- When you want to visualize output data that is too much for
Print
to handle, or when you want to copy output data to the clipboard, console output is convenient
- By outputting to
Console
instead of Print
, you can perform console output
- On Windows, it outputs to the command prompt
# include <Siv3D.hpp>
void Main()
{
Array<int32> v = { 10,20,30,40,50 };
Print << v;
// Console output
Console << v;
Console << U"Hello, Siv3D!";
while (System::Update())
{
}
}
21.20 Log Output
- By outputting to
Logger
instead of Print
, you can perform log output
- On Windows, it outputs to the Visual Studio "Output" window (during debug execution)
# include <Siv3D.hpp>
void Main()
{
Array<int32> v = { 10,20,30,40,50 };
Print << v;
// Log output
Logger << v;
Logger << U"Hello, Siv3D!";
while (System::Update())
{
}
}