PrevUpHomeNext

Misc utilities

Nothing
Ranges

This section lists several miscelaneous utility types and functions not related directly to work with OpenGL, but used by other parts of OGLplus and also utilities that are not included by oglplus/all.hpp, but can be optionally included and used by the library end-users.

#include <oglplus/utils/nothing.hpp>

Nothing is a nullary Metafunction returning itself, which serves as a nil type in OGLplus.

struct Nothing
{
	typedef Nothing Type;
};

#include <oglplus/opt/ranges.hpp>

This header implements utilities for working with types conforming to the Range concept.

All range-related utilities are implemented in the oglplus::ranges namespace:

namespace ranges {
IsRange

The IsRange boolean Metafunction allows to check if a type conforms to the Range concept:

template <typename Range>
struct IsRange
{
	typedef <Unspecified> Type; 1
};

1

std::true_type if Range conforms to the Range concept or std::false_type otherwise.

AnyRange

The AnyRange template is a type erasure for all types conforming to Range<Element> - i.e. a range whose element type is implicitly convertible to the Element type template parameter of AnyRange. AnyRange is typically used as a parameter type for functions implementing complex range algorithms.

template <typename Element>
class AnyRange
{
public:
	AnyRange(void);

	template <typename Range>
	AnyRange(Range range); 1
	template <typename Range>
	AnyRange& operator = (const Range& range);

	AnyRange(const AnyRange& other); 2
	AnyRange(AnyRange&& temp);

	AnyRange& operator = (const AnyRange& other); 3
	AnyRange& operator = (AnyRange&& other);

	typedef Element ValueType; 4
	bool Empty(void) const;
	size_t Size(void) const;
	void Next(void);
	ValueType Front(void) const;
};

template <typename Range>
AnyRange<typename Range::ValueType> EraseType(Range range); 5

1

Construction and assignment from a Range type.

2

Copy and move construction.

3

Copy and move assignment.

4

The Range interface.

5

Erases the real type of the range passed as argument.

Functions

The following functions traverse, filter of modify ranges and can be easily composed into complex algorithms.

template <typename Range>
Range Find(Range range, typename Range::ValueType value); 1

template <typename Range, typename Predicate>
Range FindIf(Range range, Predicate predicate) 2

template <typename Range>
bool Contains(Range range, typename Range::ValueType value); 3

template <typename Range, typename Predicate>
bool Has(Range range, Predicate predicate); 4

template <typename Range, typename Transf>
Range Transform(Range range, Transf transform); 5

template <typename Range, typename State, typename Func>
State Fold(Range range, State state, Func functor); 6

template <typename Range, typename Predicate>
size_t CountIf(Range range, Predicate predicate); 7

template <typename Range, typename Predicate>
Range OnlyIf(Range range, Predicate pred); 8

template <typename Element, typename R1, typename R2>
Range Concatenate(R1 r1, R2 r2); 9

1

Traverses a range and stops either if the range is empty or if the specified value is found. The resulting range is returned.

2

Finds the first a value satisfying a predicate in a range. This function traverses a range and stops either if the range is empty or if a value satisfying the predicate is found. The resulting range is returned.

3

Returns true if range contains at least one element with the specified value.

4

Returns true if range contains at least one element satisfying the specified predicate.

5

Transforms the elements in a range by an unary function. Transform returns a range whose Front member function returns the Front value of the original range transformed by transform.

6

Folds a range by using a binary functor and a state value. Fold gradually updates the state value by successively calling the specified functor on all elements with state as the first argument and the current Front element of the range as the second argument. The result of each call replaces the value stored in state. After the whole range is traversed the resulting state is returned.

7

Counts and returns the number of elements in a Range satisfying the specified predicate.

8

The OnlyIf function returns a Range that contains only those elements of the original range, which satisfy the specified predicate.

9

Returns a range that is a concatenation of the ranges r1 and r2. The ValueType of both ranges must be explicitly convertible to the specified Element type.

} // namespace ranges
Examples

Print the value names of all values in the ObjectType and the ShaderType enumerations to the standard output.

using namespace oglplus::ranges;

ForEach(
	Concatenate<StrCRef>(
		Transform(EnumValueRange<ObjectType>(), EnumValueName<ObjectType>),
		Transform(EnumValueRange<ShaderType>(), EnumValueName<ShaderType>)
	),
	[](StrCRef str)
	{
		std::cout << str << std::endl;
	}
);

Check if the GL_EXT_direct_state_access extension is implemented.

using namespace oglplus::ranges;

Context gl;

if(Contains(gl.Extensions(), "GL_EXT_direct_state_access"))
{
	std::cout << "Yay! We have DSA." << std::endl;
}

Print the number of ARB GL extensions.

using namespace oglplus::ranges;

Context gl;

std::cout << CountIf(
	gl.Extensions(),
	[](const std::string& ext) -> bool
	{
		return ext.find("_ARB_") != std::string::npos;
	}
) << std::endl;

Print the GL extension with the longest name.

using namespace oglplus::ranges;

typedef std::pair<std::size_t, std::string> length_and_name;

Context gl;

std::cout << Fold(
	gl.Extensions(),
	length_and_name(0, "N/A"),
	[](length_and_name state, std::string ext) -> length_and_name
	{
		if(state.first < ext.length())
		{
			state.first = ext.length();
			state.second = std::move(ext);
		}
		return state;
	}
).second << std::endl;

PrevUpHomeNext