-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from njoy/feature/ranges-part1
Feature/ranges part1
- Loading branch information
Showing
16 changed files
with
719 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#include "tools/concepts/Require.hpp" | ||
|
||
#include "tools/concepts/IsIterator.hpp" | ||
#include "tools/concepts/IsRange.hpp" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#ifndef NJOY_TOOLS_CONCEPTS_ISITERATOR | ||
#define NJOY_TOOLS_CONCEPTS_ISITERATOR | ||
|
||
// system includes | ||
#include <type_traits> | ||
|
||
// other includes | ||
|
||
namespace njoy { | ||
namespace tools { | ||
namespace concepts { | ||
|
||
template< typename Iterator > | ||
using iterator_category = | ||
typename std::iterator_traits< Iterator >::iterator_category; | ||
|
||
// sfinae structures for iterator objects | ||
|
||
template< typename Iterator, typename = void > | ||
struct IsIterator : std::false_type {}; | ||
|
||
template< typename Iterator > | ||
struct IsIterator< | ||
Iterator, | ||
std::void_t< iterator_category< Iterator > > > : std::true_type {}; | ||
|
||
// the following template aliases only work on iterators | ||
|
||
// sfinae structures for input iterator objects | ||
|
||
template< typename Iterator > | ||
using IsInputIterator = | ||
typename std::is_base_of< std::input_iterator_tag, | ||
iterator_category< Iterator > >; | ||
|
||
// sfinae structures for output iterator objects | ||
|
||
template< typename Iterator > | ||
using IsOutputIterator = | ||
typename std::is_base_of< std::output_iterator_tag, | ||
iterator_category< Iterator > >; | ||
|
||
// sfinae structures for forward iterator objects | ||
|
||
template< typename Iterator > | ||
using IsForwardIterator = | ||
typename std::is_base_of< std::forward_iterator_tag, | ||
iterator_category< Iterator > >; | ||
|
||
// sfinae structures for bidirectional iterator objects | ||
|
||
template< typename Iterator > | ||
using IsBidirectionalIterator = | ||
typename std::is_base_of< std::bidirectional_iterator_tag, | ||
iterator_category< Iterator > >; | ||
|
||
// sfinae structures for random access iterator objects | ||
|
||
template< typename Iterator > | ||
using IsRandomAccessIterator = | ||
typename std::is_base_of< std::random_access_iterator_tag, | ||
iterator_category< Iterator > >; | ||
|
||
} // ranges namespace | ||
} // tools namespace | ||
} // njoy namespace | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
add_cpp_test( concepts.IsIterator IsIterator.test.cpp ) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
// include Catch2 | ||
#include <catch2/catch_test_macros.hpp> | ||
|
||
// what we are testing | ||
#include "tools/concepts/IsIterator.hpp" | ||
|
||
// other includes | ||
#include <iterator> | ||
#include <forward_list> | ||
#include <list> | ||
#include <map> | ||
#include <unordered_map> | ||
#include <set> | ||
#include <unordered_set> | ||
#include <vector> | ||
|
||
// convenience typedefs | ||
using namespace njoy::tools::concepts; | ||
|
||
SCENARIO( "IsIterator sfinae objects" ) { | ||
|
||
GIVEN( "different types" ) { | ||
|
||
WHEN( "when applying IsIterator" ) { | ||
|
||
THEN( "true is returned for iterators and false for everything else" ) { | ||
|
||
// non iterator type | ||
CHECK( false == IsIterator< int >::value ); | ||
|
||
// input iterator types | ||
CHECK( true == IsIterator< std::istream_iterator< int > >::value ); | ||
|
||
// output iterator types | ||
CHECK( true == IsIterator< std::ostream_iterator< int > >::value ); | ||
|
||
// forward iterator types | ||
CHECK( true == IsIterator< std::forward_list< int >::iterator >::value ); | ||
CHECK( true == IsIterator< std::unordered_set< int >::iterator >::value ); | ||
CHECK( true == IsIterator< std::unordered_map< int, int >::iterator >::value ); | ||
|
||
// bidirectional iterator types | ||
CHECK( true == IsIterator< std::list< int >::iterator >::value ); | ||
CHECK( true == IsIterator< std::set< int >::iterator >::value ); | ||
CHECK( true == IsIterator< std::map< int, int >::iterator >::value ); | ||
|
||
// random access iterator types | ||
CHECK( true == IsIterator< std::vector< int >::iterator >::value ); | ||
} // THEN | ||
} // WHEN | ||
|
||
WHEN( "when applying IsInputIterator" ) { | ||
|
||
THEN( "true is returned for iterators that conform to input iterators" ) { | ||
|
||
// input iterator type | ||
CHECK( true == IsInputIterator< std::istream_iterator< int > >::value ); | ||
|
||
// output iterator types | ||
CHECK( false == IsInputIterator< std::ostream_iterator< int > >::value ); | ||
|
||
// forward iterator types | ||
CHECK( true == IsInputIterator< std::forward_list< int >::iterator >::value ); | ||
CHECK( true == IsInputIterator< std::unordered_set< int >::iterator >::value ); | ||
CHECK( true == IsInputIterator< std::unordered_map< int, int >::iterator >::value ); | ||
|
||
// bidirectional iterator types | ||
CHECK( true == IsInputIterator< std::list< int >::iterator >::value ); | ||
CHECK( true == IsInputIterator< std::set< int >::iterator >::value ); | ||
CHECK( true == IsInputIterator< std::map< int, int >::iterator >::value ); | ||
|
||
// random access iterator types | ||
CHECK( true == IsInputIterator< std::vector< int >::iterator >::value ); | ||
} // THEN | ||
} // WHEN | ||
|
||
WHEN( "when applying IsOutputIterator" ) { | ||
|
||
THEN( "true is returned for iterators that conform to output iterators" ) { | ||
|
||
// input iterator types | ||
CHECK( false == IsOutputIterator< std::istream_iterator< int > >::value ); | ||
|
||
// output iterator types | ||
CHECK( true == IsOutputIterator< std::ostream_iterator< int > >::value ); | ||
|
||
// forward iterator types | ||
CHECK( false == IsOutputIterator< std::forward_list< int >::iterator >::value ); | ||
CHECK( false == IsOutputIterator< std::unordered_set< int >::iterator >::value ); | ||
CHECK( false == IsOutputIterator< std::unordered_map< int, int >::iterator >::value ); | ||
|
||
// bidirectional iterator types | ||
CHECK( false == IsOutputIterator< std::list< int >::iterator >::value ); | ||
CHECK( false == IsOutputIterator< std::set< int >::iterator >::value ); | ||
CHECK( false == IsOutputIterator< std::map< int, int >::iterator >::value ); | ||
|
||
// random access iterator types | ||
CHECK( false == IsOutputIterator< std::vector< int >::iterator >::value ); | ||
} // THEN | ||
} // WHEN | ||
|
||
WHEN( "when applying IsForwardIterator" ) { | ||
|
||
THEN( "true is returned for iterators that conform to forward iterators" ) { | ||
|
||
// input iterator types | ||
CHECK( false == IsForwardIterator< std::istream_iterator< int > >::value ); | ||
|
||
// output iterator types | ||
CHECK( false == IsForwardIterator< std::ostream_iterator< int > >::value ); | ||
|
||
// forward iterator types | ||
CHECK( true == IsForwardIterator< std::forward_list< int >::iterator >::value ); | ||
CHECK( true == IsForwardIterator< std::unordered_set< int >::iterator >::value ); | ||
CHECK( true == IsForwardIterator< std::unordered_map< int, int >::iterator >::value ); | ||
|
||
// bidirectional iterator types | ||
CHECK( true == IsForwardIterator< std::list< int >::iterator >::value ); | ||
CHECK( true == IsForwardIterator< std::set< int >::iterator >::value ); | ||
CHECK( true == IsForwardIterator< std::map< int, int >::iterator >::value ); | ||
|
||
// random access iterator types | ||
CHECK( true == IsForwardIterator< std::vector< int >::iterator >::value ); | ||
} // THEN | ||
} // WHEN | ||
|
||
WHEN( "when applying IsBidirectionalIterator" ) { | ||
|
||
THEN( "true is returned for iterators that conform to bidirectional iterators" ) { | ||
|
||
// input iterator types | ||
CHECK( false == IsBidirectionalIterator< std::istream_iterator< int > >::value ); | ||
|
||
// output iterator types | ||
CHECK( false == IsBidirectionalIterator< std::ostream_iterator< int > >::value ); | ||
|
||
// forward iterator types | ||
CHECK( false == IsBidirectionalIterator< std::forward_list< int >::iterator >::value ); | ||
CHECK( false == IsBidirectionalIterator< std::unordered_set< int >::iterator >::value ); | ||
CHECK( false == IsBidirectionalIterator< std::unordered_map< int, int >::iterator >::value ); | ||
|
||
// bidirectional iterator types | ||
CHECK( true == IsBidirectionalIterator< std::list< int >::iterator >::value ); | ||
CHECK( true == IsBidirectionalIterator< std::set< int >::iterator >::value ); | ||
CHECK( true == IsBidirectionalIterator< std::map< int, int >::iterator >::value ); | ||
|
||
// random access iterator types | ||
CHECK( true == IsBidirectionalIterator< std::vector< int >::iterator >::value ); | ||
} // THEN | ||
} // WHEN | ||
|
||
WHEN( "when applying IsRandomAccessIterator" ) { | ||
|
||
THEN( "true is returned for iterators that conform to random access iterators" ) { | ||
|
||
// input iterator types | ||
CHECK( false == IsRandomAccessIterator< std::istream_iterator< int > >::value ); | ||
|
||
// output iterator types | ||
CHECK( false == IsRandomAccessIterator< std::ostream_iterator< int > >::value ); | ||
|
||
// forward iterator types | ||
CHECK( false == IsRandomAccessIterator< std::forward_list< int >::iterator >::value ); | ||
CHECK( false == IsRandomAccessIterator< std::unordered_set< int >::iterator >::value ); | ||
CHECK( false == IsRandomAccessIterator< std::unordered_map< int, int >::iterator >::value ); | ||
|
||
// bidirectional iterator types | ||
CHECK( false == IsRandomAccessIterator< std::list< int >::iterator >::value ); | ||
CHECK( false == IsRandomAccessIterator< std::set< int >::iterator >::value ); | ||
CHECK( false == IsRandomAccessIterator< std::map< int, int >::iterator >::value ); | ||
|
||
// random access iterator types | ||
CHECK( true == IsRandomAccessIterator< std::vector< int >::iterator >::value ); | ||
} // THEN | ||
} // WHEN | ||
} // GIVEN | ||
} // SCENARIO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#ifndef NJOY_TOOLS_CONCEPTS_ISRANGE | ||
#define NJOY_TOOLS_CONCEPTS_ISRANGE | ||
|
||
// system includes | ||
#include <type_traits> | ||
|
||
// other includes | ||
|
||
namespace njoy { | ||
namespace tools { | ||
namespace concepts { | ||
|
||
template< typename Range, typename = void > | ||
struct IsRange : std::false_type {}; | ||
|
||
template< typename Range > | ||
struct IsRange< Range, | ||
std::void_t< decltype( std::begin( std::declval< Range >() ) ), | ||
decltype( std::end( std::declval< Range >() ) ) | ||
> > : std::true_type {}; | ||
|
||
} // ranges namespace | ||
} // tools namespace | ||
} // njoy namespace | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
add_cpp_test( concepts.IsRange IsRange.test.cpp ) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// include Catch2 | ||
#include <catch2/catch_test_macros.hpp> | ||
|
||
// what we are testing | ||
#include "tools/concepts/IsRange.hpp" | ||
|
||
// other includes | ||
#include <vector> | ||
#include <map> | ||
|
||
// convenience typedefs | ||
using namespace njoy::tools::concepts; | ||
|
||
SCENARIO( "IsRange" ) { | ||
|
||
GIVEN( "different types" ) { | ||
|
||
WHEN( "when applying IsRange" ) { | ||
|
||
THEN( "true is returned for ranges and false for everything else" ) { | ||
|
||
CHECK( false == IsRange< int >::value ); | ||
|
||
CHECK( true == IsRange< std::vector< int > >::value ); | ||
CHECK( true == IsRange< const std::vector< int > >::value ); | ||
CHECK( true == IsRange< std::map< int, int > >::value ); | ||
} // THEN | ||
} // WHEN | ||
} // GIVEN | ||
} // SCENARIO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#ifndef NJOY_TOOLS_CONCEPTS_REQUIRES | ||
#define NJOY_TOOLS_CONCEPTS_REQUIRES | ||
|
||
// system includes | ||
#include <type_traits> | ||
|
||
// other includes | ||
|
||
namespace njoy { | ||
namespace tools { | ||
namespace concepts { | ||
|
||
template< bool TrueFalse, template< typename...> class Concept, typename... T > | ||
using Requires = typename std::enable_if< Concept< T... >::value == TrueFalse, bool >::type; | ||
|
||
} // ranges namespace | ||
} // tools namespace | ||
} // njoy namespace | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
add_cpp_test( concepts.Requires Requires.test.cpp ) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// include Catch2 | ||
#include <catch2/catch_test_macros.hpp> | ||
|
||
// what we are testing | ||
#include "tools/concepts/Requires.hpp" | ||
|
||
// other includes | ||
|
||
// convenience typedefs | ||
using namespace njoy::tools::concepts; | ||
|
||
template< typename T, Requires< true, std::is_integral, T > = true > | ||
bool integer_type( const T& ){ return true; } | ||
|
||
template< typename T, Requires< false, std::is_integral, T > = true > | ||
bool integer_type( const T& ){ return false; } | ||
|
||
SCENARIO( "Require" ) { | ||
|
||
GIVEN( "different types" ) { | ||
|
||
WHEN( "when applying Require" ) { | ||
|
||
THEN( "true is returned for integers and false for everything else" ) { | ||
|
||
CHECK( true == integer_type( 1 ) ); | ||
CHECK( false == integer_type( 1.0 ) ); | ||
CHECK( false == integer_type( std::vector< int >{} ) ); | ||
} // THEN | ||
} // WHEN | ||
} // GIVEN | ||
} // SCENARIO |
Oops, something went wrong.