util.hpp
The cslt namespace implements an independend version of the
utilities.h header file
in the util.hpp file which can be accessed below. This file provides
generic template functions and classes for important but unrelated functions
that are useful in a wide variety of applications.
The attributes, functions and objects of the util.hpp header file are described
below.
cslt::pair
The pair template struct is implemented to pair values of like or different
types.
Public Attributes
first: The first data variable contained by
pair.second: The second data variable contained by
pair.
Constructors
- template <class A, class B> pair(const A &first_val, const B &second_val)
Constructs the
pairobject with two values.- Parameters:
A – The data type of
first.B – The data type of
second.&first_val (const A) – The first value to be stored in the struct.
&second_val (const B) – The second value to be stored in the struct.
- pair(const pair &other)
Copy constructor for the class. :param const pair &other: An object of type
pair.
Operator
- pair pair& operator=(const pair &other)
Overloads the
=operator such that this class will become a deep copy of the other object. The data types must be the same between the two objects.- Parameters:
&other (const pair) – An object of type
pair.
Methods
- void swap(pair &other)
Swaps the data between this and other objects. The data types must be the same between the two classes.
- Parameters:
&other (pair) – An object of type
pair.
Example
#include "io.hpp"
#include "util.hpp"
int main() {
cslt::pair<int, float> a(2, 32.1);
cslt::cout << "First Value: " << a.first << cslt::endl;
cslt::cout << "Second Value: " << a.second << cslt::endl;
return 0;
}
>> First Value: 2
>> Second Value: 32.10000
cslt::make_pair
The make_pair function provides a convenient way to instantiate a
pair object.
- pair <A, B> template<class A, class B> make_pair(const A &first_val, const B &second_val)
Instantiates a
pairobject and returns it to the user.- Parameters:
A – The data type associated with the first variable.
B – The data type associated with the second variable.
first_val – The first value to be stored by the struct.
second_val – The second value to be stored by the struct.
- Returns pair:
An object of type
pair.
Example 1
This example demonstrates how to use make_pair to instantiate an object,
and the overloaded = operator.
#include "io.hpp"
#include "util.hpp"
int main() {
cslt::pair <float,int> planet, homeplanet;
planet = cslt::make_pair(37.1f,6371);
// If variable not defined, you can implement the auto keyword for data types.
// auto new_planet = cslt::make_pair(12.1, 3);
planet = cslt::make_pair(37.1f,6371);
homeplanet = planet;
cslt::cout << homeplanet.first << cslt::endl;
cslt::cout << homeplanet.second << cslt::endl;
return 0;
}
>> 37.10000
>> 6371
Example 2
This example demonstrates the use of the swap method
#include "io.hpp"
#include "util.hpp"
int main() {
cslt::pair<int, int> one = cslt::make_pair(1, 2);
cslt::pair<int, int> two = cslt::make_pair(3, 4);
one.swap(two);
cslt::cout << "one.first: " << one.first << cslt::endl;
cslt::cout << "one.second: " << one.second << cslt::endl;
cslt::cout << "two.first: " << two.first << cslt::endl;
cslt::cout << "two.second: " << two.second << cslt::endl;
return 0;
}
>> one.first: 3
>> one.second: 4
>> two.first: 1
>> two.second: 2
cslt::move
-
template<typename T>
typename remove_reference<T>::type &&move(T &&arg) The
movefunction template is used to cast its argument to an rvalue reference. This enables the use of move semantics in C++, allowing for efficient transfer of resources from one object to another.The function takes a universal reference (also known as a forwarding reference) as its parameter, allowing it to accept both lvalue and rvalue references. The return type is an rvalue reference to the type of arg, with any reference qualifiers removed, facilitating the move operation.
Template Parameters
T : The type of the argument. The actual type is deduced from the argument passed to the function.
Function Parameters
arg : A universal reference to the object that is to be moved.
Return Value
The function returns an rvalue reference to arg after casting.
Usage Example
Example
#include "util.hpp"
#include "io.hpp"
class TestClass {
public:
int value = 5;
}
int main() {
cslt::TestClass obj;
cslt::cout << "Data in obj: " << obj.a << cslt::endl;
cslt::TestClass moved_obj = cslt::move(obj);
// At this point move_obj contains data and obj is in an unspecified state
cslt::cout << "Data now in moved_obj: " << moved_obj.a << cslt::endl;
return 0;
}
>> Data in obj: 5
>> Data now in moved_obj: 5
In this example, an object of TestClass is moved using the move function. After the move, obj is in a moved-from state, and moved_obj has taken ownership of the resources originally held by obj.
Note
The actual moving of resources is performed by the move constructors and move assignment operators of the types involved. The move function only enables these operations by casting its argument to an rvalue reference.
cslt::move_if_noexcept
This function is a wrapper around the C++ Standard Library’s std::move_if_noexcept.
It conditionally casts its argument to an rvalue reference, enabling move semantics
if the move operation is declared noexcept. Otherwise, it falls back to copy
semantics to avoid throwing exceptions during move operations.
The purpose of this wrapper is to integrate std::move_if_noexcept seamlessly
within the cslt namespace, allowing users of the library to utilize
standard move semantics optimizations while maintaining consistent namespace usage.
Template Parameters
T: The type of the argument to be conditionally moved.
Parameters
x: A reference to the object of type
Tthat will be moved or copied, depending on its noexcept guarantee.
Return Value
Returns an rvalue reference to
Tif the move operation ofTis noexcept; otherwise, returnsxas is, promoting copy semantics.
Example
In this example, cslt::move_if_noexcept is used to conditionally move
myPair. The actual operation (move or copy) depends on the noexcept guarantee
of the move constructor for cslt::pair<int, std::string>.
cslt::pair<int, std::string> myPair(42, "example");
auto movedPair = cslt::move_if_noexcept(myPair);
// Use movedPair as needed...
cslt::forward
This function is a custom implementation of the C++ Standard Library’s std::forward.
It is designed to perfectly forward a function argument to another function, preserving
the argument’s value category (lvalue or rvalue). This enables the efficient use of resources
and optimizations, such as move semantics, without inadvertently altering the original
semantic intentions of the passed arguments.
The cslt::forward function is pivotal in template programming, especially when creating
generic functions or classes that need to forward arguments to constructors or other functions
with perfect fidelity. It is a cornerstone of perfect forwarding, allowing developers to
write more generic, efficient, and safe code by ensuring that resources are moved only when
it is safe to do so.
Template Parameters
T: The type of the argument to be forwarded. This type includes both lvalue and rvalue reference qualifiers to enable perfect forwarding.
Parameters
arg: A reference to the object of type
T. Depending on the invocation context,argcan be an lvalue reference (if an lvalue is passed) or an rvalue reference (if an rvalue is passed), enabling the function to forward it appropriately.
Return Value
Returns the argument cast to an rvalue reference of type
Tif called with an rvalue, otherwise returns the argument itself, preserving its lvalue reference category. This allows the caller function or constructor to utilize the argument as intended, with move semantics applied only where permissible.
Example
In this example, cslt::forward is used to forward arguments to a constructor of
MyClass. This demonstrates how cslt::forward enables perfect forwarding, allowing
the constructor to utilize move semantics when possible.
template<typename... Args>
MyClass createMyClass(Args&&... args) {
return MyClass(cslt::forward<Args>(args)...);
}
MyClass myObj = createMyClass(10, "example");
In this usage, arguments passed to createMyClass are perfectly forwarded to
MyClass’s constructor, preserving their original value categories (lvalue or rvalue).