Commit c1f5e490 by Bryan Hou

submission

parents
Showing with 4973 additions and 0 deletions
// compiled with: g++-9 -fconcepts -std=c++2a -Irange-v3-master/include final.cpp -o ./main
#include <iostream>
#include <string>
#include <vector>
#include <type_traits>
#include <algorithm>
#include <fstream>
#include <range/v3/all.hpp>
#include <regex>
#include <functional>
using std::getline;
using std::smatch;
using std::regex_search;
using std::regex;
using std::fstream;
using std::ofstream;
using std::ostream;
using std::string;
using std::cout;
using std::endl;
using std::vector;
using std::remove;
using std::move;
using ranges::max_element;
using std::true_type;
using std::false_type;
using std::void_t;
using std::is_same_v;
using std::enable_if_t;
using std::forward;
using std::function;
extern ofstream logstream("Characterlog.txt");
template<typename T>
concept bool canHoldItem = requires (T t) {
typename T::item_list;
};
template<typename T>
concept bool canAttack = requires (T t) {
{t.atk_pts > 0}-> bool;
};
template<typename T>
concept bool canDefend = requires (T t) {
{t.def_pts > 0}-> bool;
};
template<typename T>
concept bool hasHealth = requires (T t) {
{t.health} -> int;
};
template<typename T>
concept bool canBattle = requires (T t) {
requires canDefend<T> && canAttack<T>;
requires hasHealth<T>;
};
struct Item{
Item(string n="NullItem", int p=0, int atk=0, int def=0):
name(n), price(p), atk_pts(atk), def_pts(def) {}
string name;
long price;
friend ostream& operator<<(ostream& os, Item const & i)
{
os << "Item name:" << i.name;
return os;
}
int atk_pts;
int def_pts;
};
struct Weapon: public Item{
Weapon(string n, int p=0, int atk=0, int def=0): Item(n, p, atk, def){
}
};
struct MiscItem: public Item{
MiscItem(string n, int p=0): Item(n,p) {
}
};
struct CharacterHelper {
static bool def_item_comparator(Item const & a, Item const & b) {
return a.def_pts < b.def_pts;
}
int max_element_wrap(vector<Item> i_l, bool (*fp)(Item const &, Item const &), string opt) {
if (opt == "def") {
// ranges
return max_element(i_l, fp)->def_pts;
} else {
return max_element(i_l, fp)->atk_pts;
}
}
};
// Abilities is really just a custom tuple with perfect forwarding. was going to write enable_if to only allow certain types
template<class ...Ts>
struct Abilities;
template<>
struct Abilities<> {};
template<class T, class ...Ts>
struct Abilities<T, Ts...> : public Abilities<Ts...>
{
Abilities(T && t, Ts &&... ts) : Abilities<Ts...>(forward<Ts>(ts)...), value(forward<T>(t)){}
T value;
};
template<int i, class ...Ts>
struct Get;
template<class T, class ...Ts>
struct Get<0, T, Ts...> {
static auto &get(Abilities<T, Ts...> &ability) {
return ability.value;
}
};
template<int i, class T, class ...Ts>
struct Get<i, T, Ts...> {
static auto &get(Abilities<T, Ts...> &ability) {
return Get<i - 1, Ts...>::get(static_cast<Abilities<Ts...>&>(ability));
}
};
template<int i, class ...Ts>
auto &
get(Abilities<Ts...> &ability) {
return Get<i, Ts...>::get(ability);
}
// enable if
template <typename T, typename = void>
struct has_peaceful_tag : false_type { };
template <typename T>
struct has_peaceful_tag<T, void_t<typename T::tag>> : true_type { };
template <typename T,
enable_if_t<has_peaceful_tag<T>::value>* = nullptr>
string check_if_peaceful(T const & obj) {
return "peaceful";
}
template <typename T,
enable_if_t<!has_peaceful_tag<T>::value>* = nullptr>
string check_if_peaceful(T const & obj) {
return "not peaceful";
}
struct Peaceful_Tag{};
struct PeacefulCharacter
{
using tag = Peaceful_Tag;
// Perfect forwarding
PeacefulCharacter(string n, vector<Item>&& i_l): name(n), item_list(forward<vector<Item> >(i_l)), abilities("escort", "bless") {
logstream << n << " is born!" << endl;
cout << '\n' << n << " is born!" << endl;
}
friend ostream& operator<<(ostream& os, PeacefulCharacter const & c)
{
os << "Name:" << c.name << endl;
os << "Items Possessed:" << endl;
for (auto i: c.item_list){
os << i.name << endl;
}
return os;
}
private:
string name;
vector<Item> item_list;
Abilities<string, string> abilities;
};
struct BattleReadyCharacter
{
BattleReadyCharacter(string n, vector<Item>&& i_l): name(n), item_list(std::forward<vector<Item>>(i_l)), health(100), abilities("escort", "bless") {
logstream << n << " is born!" << endl;
cout << '\n' << n << " is born!" << endl;
// function pointer to lambda
bool (*atk_fp)(Item const &, Item const &) = [](Item const &a, Item const &b){return a.atk_pts < b.atk_pts;};
// function pointer to normal function
bool (*def_fp)(Item const &, Item const &) = &CharacterHelper::def_item_comparator;
int (CharacterHelper::*max_el_fp) (vector<Item> i_l, bool (*fp)(Item const &, Item const &), string opt) = &CharacterHelper::max_element_wrap;
CharacterHelper ch;
// function pointer to member function
atk_pts = (ch.*max_el_fp)(item_list, atk_fp, "atk");
def_pts = (ch.*max_el_fp)(item_list, def_fp, "def");
}
friend ostream& operator<<(ostream& os, const BattleReadyCharacter& c)
{
os << "Name:" << c.name << endl;
os << "Items Possessed:" << endl;
for (auto i: c.item_list){
os << i.name << endl;
}
return os;
}
string name;
vector<Item> item_list;
int health;
int def_pts;
int atk_pts;
Abilities<string, string> abilities;
};
template<class C, class D>
requires canBattle<C> && canBattle<D>
void attack(C & c1, D & d1){
if (c1.health > 0){
d1.health -= c1.atk_pts-d1.def_pts;
cout << c1.name << " deals " << c1.atk_pts-d1.def_pts << " damage. ";
if (d1.health <= 0) {
d1.health = 0;
logstream << d1.name << " died." << endl;
cout << d1.name << " died." << endl;
} else {
cout << d1.name << " has " << d1.health << " health now." << endl;
}
} else {
cout << c1.name << " can't attack because he is dead." << endl;
}
}
//variadic templates
template<typename ... Args>
void printer(Args ... args)
{
((cout << args << ", "), ...);
}
void print_character_status() {
fstream fs("Characterlog.txt", fs.in);
smatch sm;
regex name_find = regex("(?:([a-zA-Z]*) is born!|([a-zA-Z]*) died.)");
vector<string> alive_list;
vector<string> dead_list;
if (!fs.is_open()) {
cout << "Failed to open Characterlog.txt.\n";
} else {
string str;
while(getline(fs, str)){
regex_search(str, sm, name_find);
if (sm[1] != "") {
alive_list.push_back(sm[1]);
}
if (sm[2] != "") {
dead_list.push_back(sm[2]);
}
}
}
fs.close();
// remove dead characters
for (auto i: dead_list) {
alive_list.erase(remove(alive_list.begin(), alive_list.end(), i),
alive_list.end());
}
cout << "Characters still alive and kicking:" << endl;
for (auto i: alive_list){
cout << i << '\n';
}
cout << "Dead characters (RIP):\n";
for (auto i: dead_list){
cout << i << '\n';
}
}
int main() {
Weapon a("shield", 15, 10, 30);
Weapon b("sword", 15, 90, 20);
MiscItem c("rock");
//printing with fold expression
printer(a,b,c);
Weapon d("knife",15, 30);
Weapon e("chainsaw",15, 70);
MiscItem f("hay");
MiscItem g("grass");
Weapon h("stick", 20);
vector<Item> inv1 = {a,b,c};
vector<Item> inv2 = {d,e,f,g};
vector<Item> inv3 = {h};
BattleReadyCharacter ash("Ash", move(inv1));
cout << ash;
BattleReadyCharacter bob("Bob", move(inv2));
PeacefulCharacter cam("Cameron", move(inv3));
cout << bob.atk_pts << endl;
cout << bob.def_pts << endl;
attack(bob, ash);
attack(ash, bob);
attack(ash, bob);
attack(bob, ash);
cout << "Bob is " << check_if_peaceful(bob) << endl;
cout << "Cam is " << check_if_peaceful(cam) << endl;
//std::function
function<void(void)> print_character_status_wrap = print_character_status;
// Using concepts
// attack(bob, cam); // error: peaceful character cannot be attacked or attack
// attack(ash, cam); // error: peaceful character cannot be attacked or attack
logstream.close();
// use regex to find out who has died from the logs
cout << "\nCHARACTER STATUS" << endl;
print_character_status_wrap();
return 0;
}
{
AccessModifierOffset: -4,
AlignAfterOpenBracket: Align,
AlignEscapedNewlinesLeft: true,
AlignTrailingComments: true,
AllowAllParametersOfDeclarationOnNextLine: false,
AllowShortBlocksOnASingleLine: true,
AllowShortCaseLabelsOnASingleLine: false,
AllowShortFunctionsOnASingleLine: None,
AllowShortIfStatementsOnASingleLine: false,
AllowShortLoopsOnASingleLine: false,
AlwaysBreakBeforeMultilineStrings: true,
AlwaysBreakAfterReturnType: None,
AlwaysBreakTemplateDeclarations: true,
BinPackArguments: false,
BinPackParameters: true,
BraceWrapping: {
AfterCaseLabel: true,
AfterClass: true,
AfterControlStatement: true,
AfterEnum: true,
AfterFunction: true,
AfterNamespace: true,
AfterStruct: true,
AfterUnion: true,
AfterExternBlock: true,
BeforeCatch: true,
BeforeElse: true,
IndentBraces: false,
SplitEmptyFunction: false,
SplitEmptyRecord: false,
SplitEmptyNamespace: true,
},
BreakBeforeBinaryOperators: false,
BreakBeforeBraces: Custom,
BreakBeforeTernaryOperators: true,
BreakConstructorInitializers: BeforeComma,
BreakInheritanceList: BeforeComma,
ColumnLimit: 90,
ConstructorInitializerAllOnOneLineOrOnePerLine: false,
ConstructorInitializerIndentWidth: 2,
ContinuationIndentWidth: 4,
Cpp11BracedListStyle: true,
DerivePointerAlignment: false,
ExperimentalAutoDetectBinPacking: false,
ForEachMacros: ['RANGES_FOR',],
IncludeBlocks: Regroup,
IncludeCategories: [
{ Regex: '^<range/v3/range_fwd.hpp',
Priority: 5},
{ Regex: '^<range/v3',
Priority: 6},
{ Regex: '^<concepts/',
Priority: 4},
{ Regex: '^<meta/',
Priority: 3},
{ Regex: '^<std/.*>$',
Priority: 2},
{ Regex: '^<.*>$',
Priority: 1},
],
IndentCaseLabels: false,
IndentFunctionDeclarationAfterType: false,
IndentWidth: 4,
KeepEmptyLinesAtTheStartOfBlocks: true,
Language: Cpp,
MaxEmptyLinesToKeep: 1,
MacroBlockBegin: "^(RANGES|META)_BEGIN_NAMESPACE_(STD|VERSION|CONTAINER)$",
MacroBlockEnd: "^(RANGES|META)_END_NAMESPACE_(STD|VERSION|CONTAINER)$",
NamespaceIndentation: All,
PenaltyBreakBeforeFirstCallParameter: 10,
PenaltyReturnTypeOnItsOwnLine: 1000,
PointerAlignment: Middle,
SpaceAfterControlStatementKeyword: false,
SpaceAfterTemplateKeyword: false,
SpaceBeforeAssignmentOperators: true,
SpaceBeforeParens: Never,
SpaceInEmptyParentheses: false,
SpacesBeforeTrailingComments: 1,
SpacesInAngles: false,
SpacesInCStyleCastParentheses: false,
SpacesInParentheses: false,
Standard: Cpp11,
StatementMacros: [
'RANGES_INLINE_VARIABLE',
'RANGES_DEFINE_CPO',
'CPP_member',
'CPP_broken_friend_member',
],
TabWidth: 4,
UseTab: Never,
}
*.hpp text
*.cpp text
*.txt text
*.html text
*.md text
*.yml text
*.xml text
*.in text
.gitattributes text
.gitignore text
*.cmd -text
*.sln -text
*.vcxproj -text
*.vcxproj.filters -text
## Copyright (c) 2013 GitHub, Inc.
##
## Permission is hereby granted, free of charge, to any person obtaining a
## copy of this software and associated documentation files (the "Software"),
## to deal in the Software without restriction, including without limitation
## the rights to use, copy, modify, merge, publish, distribute, sublicense,
## and/or sell copies of the Software, and to permit persons to whom the
## Software is furnished to do so, subject to the following conditions:
##
## The above copyright notice and this permission notice shall be included in
## all copies or substantial portions of the Software.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
## FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
## DEALINGS IN THE SOFTWARE.
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
# Clion files
.idea
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
x64/
build*/
bld/
[Bb]in/
[Oo]bj/
bazel-*
cmake-build-*/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
#NUNIT
*.VisualState.xml
TestResult.xml
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding addin-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.azurePubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
## TODO: If the tool you use requires repositories.config, also uncomment the next line
#!packages/repositories.config
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Buck build artefacts
.buckd/
buck-out/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Visual Studio stuff
*.VC.db
*.VC.opendb
.vscode/
.vs/
\#*#
.#*
[submodule "doc/gh-pages"]
path = doc/gh-pages
url = https://github.com/ericniebler/range-v3.git
branch = gh-pages
# Copyright Louis Dionne 2013-2016
# Copyright Gonzalo BG 2014-2017
# Copyright Julian Becker 2015
# Copyright Manu Sánchez 2015
# Copyright Casey Carter 2015-2017
# Copyright Eric Niebler 2015-2016
# Copyright Paul Fultz II 2015-2016
# Copyright Jakub Szuppe 2016.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt)
# Adapted from various sources, including:
# - Louis Dionne's Hana: https://github.com/ldionne/hana
# - Paul Fultz II's FIT: https://github.com/pfultz2/Fit
language: cpp
sudo: true
script: cmake
git:
depth: 1
env:
global:
- DEPS_DIR=${TRAVIS_BUILD_DIR}/deps
- CMAKE_VERSION="3.12.0"
cache:
directories:
- ${DEPS_DIR}/cmake-${CMAKE_VERSION}
matrix:
include:
- env: BUILD_TYPE=Release CPP=1z SYSTEM_LIBCXX=On
os: osx
compiler: clang
# The ASAN build in install_libcxx.sh doesn't work for versions < 4
# clang 3.6 C++17/14 Release libc++
- env: CLANG_VERSION=3.6 BUILD_TYPE=Release CPP=14 LIBCXX=On HEADERS=On
os: linux
addons: &clang36
apt:
packages:
- clang-3.6
- libstdc++-5-dev
- valgrind
sources:
- ubuntu-toolchain-r-test
# clang 3.7 C++17/14 Release libc++
- env: CLANG_VERSION=3.7 BUILD_TYPE=Release CPP=14 LIBCXX=On HEADERS=On
os: linux
addons: &clang37
apt:
packages:
- clang-3.7
- libstdc++-5-dev
- valgrind
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-3.7
- sourceline: 'deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.7 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
# clang 3.8 C++17/14 Release libc++
- env: CLANG_VERSION=3.8 BUILD_TYPE=Release CPP=1z LIBCXX=On
os: linux
addons: &clang38
apt:
packages:
- util-linux
- clang-3.8
- libstdc++-5-dev
- valgrind
sources:
- ubuntu-toolchain-r-test
- env: CLANG_VERSION=3.8 BUILD_TYPE=Release CPP=14 LIBCXX=On HEADERS=On
os: linux
addons: *clang38
# clang 3.9 C++17/14 Release libc++
- env: CLANG_VERSION=3.9 BUILD_TYPE=Release CPP=1z LIBCXX=On
os: linux
addons: &clang39
apt:
packages:
- util-linux
- clang-3.9
- libstdc++-6-dev
- valgrind
sources:
- ubuntu-toolchain-r-test
- env: CLANG_VERSION=3.9 BUILD_TYPE=Release CPP=14 LIBCXX=On HEADERS=On
os: linux
addons: *clang39
# clang 5 C++17/14/1z Debug/Release-ASAN libc++, 17 Debug libstdc++
- env: CLANG_VERSION=5.0 BUILD_TYPE=Debug CPP=1z LIBCXX=On
os: linux
addons: &clang5
apt:
packages:
- clang-5.0
- libstdc++-6-dev
- valgrind
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-5.0
- sourceline: 'deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-5.0 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- env: CLANG_VERSION=5.0 BUILD_TYPE=Release CPP=1z ASAN=On LIBCXX=On HEADERS=On
os: linux
addons: *clang5
- env: CLANG_VERSION=5.0 BUILD_TYPE=Debug CPP=14 LIBCXX=On
os: linux
addons: *clang5
- env: CLANG_VERSION=5.0 BUILD_TYPE=Release CPP=14 ASAN=On LIBCXX=On
os: linux
addons: *clang5
- env: CLANG_VERSION=5.0 BUILD_TYPE=Release CPP=1z
os: linux
addons: *clang5
# Module build is on the floor
# - env: CLANG_VERSION=5.0 BUILD_TYPE=Release CPP=1z MSAN=On LIBCXX=On CLANG_MODULES=On
# os: linux
# addons: *clang5
# gcc-5 C++17/C++14 Release
- env: GCC_VERSION=5 BUILD_TYPE=Release CPP=1z
os: linux
addons: &gcc5
apt:
packages:
- g++-5
- valgrind
sources:
- ubuntu-toolchain-r-test
- env: GCC_VERSION=5 BUILD_TYPE=Release CPP=14 HEADERS=On
os: linux
addons: *gcc5
# gcc-6 C++17/14/1z Debug/Release
- env: GCC_VERSION=6 BUILD_TYPE=Debug CPP=1z
os: linux
addons: &gcc6
apt:
packages:
- g++-6
- valgrind
sources:
- ubuntu-toolchain-r-test
- env: GCC_VERSION=6 BUILD_TYPE=Release CPP=1z
os: linux
addons: *gcc6
- env: GCC_VERSION=6 BUILD_TYPE=Debug CPP=14 HEADERS=On
os: linux
addons: *gcc6
- env: GCC_VERSION=6 BUILD_TYPE=Release CPP=14
os: linux
addons: *gcc6
# gcc-7 C++17/14/1z Debug/Release
- env: GCC_VERSION=7 BUILD_TYPE=Debug CPP=1z
os: linux
addons: &gcc7
apt:
packages:
- g++-7
- valgrind
sources:
- ubuntu-toolchain-r-test
- env: GCC_VERSION=7 BUILD_TYPE=Release CPP=1z
os: linux
addons: *gcc7
- env: GCC_VERSION=7 BUILD_TYPE=Debug CPP=14 HEADERS=On
os: linux
addons: *gcc7
- env: GCC_VERSION=7 BUILD_TYPE=Release CPP=14
os: linux
addons: *gcc7
- env: GCC_VERSION=7 BUILD_TYPE=Release CPP=1z CONCEPTS=On
os: linux
addons: *gcc7
# gcc-8 C++17/14/1z Debug/Release
- env: GCC_VERSION=8 BUILD_TYPE=Debug CPP=1z
os: linux
addons: &gcc8
apt:
packages:
- g++-8
- valgrind
sources:
- ubuntu-toolchain-r-test
- env: GCC_VERSION=8 BUILD_TYPE=Release CPP=1z
os: linux
addons: *gcc8
- env: GCC_VERSION=8 BUILD_TYPE=Debug CPP=14 HEADERS=On
os: linux
addons: *gcc8
- env: GCC_VERSION=8 BUILD_TYPE=Release CPP=14
os: linux
addons: *gcc8
- env: GCC_VERSION=8 BUILD_TYPE=Release CPP=1z CONCEPTS=On
os: linux
addons: *gcc8
# Install dependencies
before_install:
- set -e
- |
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
brew update
brew install gnu-sed
brew install gnu-which
brew upgrade cmake
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
elif [ "$BUILD_TYPE" == "Release" -a "$ASAN" != "On" -a "$MSAN" != "On" ]; then
USE_VALGRIND=On
fi
- |
if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
if [ -f ${DEPS_DIR}/cmake-${CMAKE_VERSION}/cached ]; then
echo "Using cached cmake version ${CMAKE_VERSION}."
else
CMAKE_URL="https://cmake.org/files/v3.12/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz"
mkdir -p ${DEPS_DIR}/cmake-${CMAKE_VERSION}
travis_retry wget --no-check-certificate --quiet -O - "${CMAKE_URL}" | tar --strip-components=1 -xz -C ${DEPS_DIR}/cmake-${CMAKE_VERSION}
touch ${DEPS_DIR}/cmake-${CMAKE_VERSION}/cached
fi
export PATH="${DEPS_DIR}/cmake-${CMAKE_VERSION}/bin:${PATH}"
fi
- if [ -n "$GCC_VERSION" ]; then export CXX="g++-${GCC_VERSION}" CC="gcc-${GCC_VERSION}"; fi
- if [ -n "$CLANG_VERSION" ]; then export CXX="clang++-${CLANG_VERSION}" CC="clang-${CLANG_VERSION}"; fi
- which $CXX && $CXX --version
- which $CC
- if [ "$USE_VALGRIND" == "On" ]; then which valgrind; fi
- if [ "$ASAN" == "On" ]; then export SANITIZER="Address;Undefined"; fi
- if [ "$MSAN" == "On" ]; then export SANITIZER="MemoryWithOrigins"; fi
- if [ -n "$CLANG_VERSION" ]; then PATH="${PATH}" CXX="$CXX" CC="$CC" ./install_libcxx.sh; fi
install:
# Workaround for valgrind bug: https://bugs.kde.org/show_bug.cgi?id=326469.
# It is fixed in valgrind 3.10 so this won't be necessary if someone
# replaces the current valgrind (3.7) with valgrind-3.10
- |
if [ "$USE_VALGRIND" == "On" ]; then
sed -i 's/march=native/msse4.2/' cmake/ranges_flags.cmake
# We need to explicitly initialize std::random_device on libstdc++ to avoid using RDRAND
# since valgrind doesn't understand the instruction.
CXX_FLAGS="${CXX_FLAGS} -DRANGES_WORKAROUND_VALGRIND_RDRAND"
fi
- if [ "$GCC_VERSION" == "5" ]; then CXX_FLAGS="${CXX_FLAGS} -DRANGES_CXX_CONSTEXPR=RANGES_CXX_CONSTEXPR11"; fi
- |
if [ "$LIBCXX" == "On" ]; then
CXX_FLAGS="${CXX_FLAGS} -stdlib=libc++ -nostdinc++ -cxx-isystem ${TRAVIS_BUILD_DIR}/llvm/include/c++/v1/ -Wno-unused-command-line-argument"
CXX_LINKER_FLAGS="${CXX_LINKER_FLAGS} -L ${TRAVIS_BUILD_DIR}/llvm/lib -Wl,-rpath,${TRAVIS_BUILD_DIR}/llvm/lib -lc++abi"
if [ -n "$CLANG_VERSION" ]; then
if [ "$ASAN" == "On" ]; then
CXX_FLAGS="${CXX_FLAGS} -fsanitize=address"
elif [ "$MSAN" == "On" ]; then
CXX_FLAGS="${CXX_FLAGS} -fsanitize=memory"
fi
fi
fi
- mkdir -p build
# This cd works, but causes the shell to exit on OSX with set -e. I don't even.
- set +e; cd build; set -e; pwd
- cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_FLAGS="${CXX_FLAGS}" -DCMAKE_EXE_LINKER_FLAGS="${CXX_LINKER_FLAGS}" -DRANGES_CXX_STD=$CPP -DRANGE_V3_HEADER_CHECKS=$HEADERS -DRANGES_PREFER_REAL_CONCEPTS=$CONCEPTS -DRANGES_VERBOSE_BUILD=On -DRANGES_ASAN=$ASAN -DRANGES_MSAN=$MSAN -DRANGES_DEEP_STL_INTEGRATION=On -Wdev
- cat CMakeFiles/CMakeError.log || true
- cat CMakeFiles/CMakeOutput.log || true
- if [ "$CLANG_MODULES" == "On" -a "$LIBCXX" == "On" ]; then cmake .. -DRANGES_MODULES=On -DRANGES_LIBCXX_MODULE="${TRAVIS_BUILD_DIR}/llvm/include/c++/v1/module.modulemap"; fi
- make -j2 VERBOSE=1
script:
- if [ "$USE_VALGRIND" == "On" ]; then CTEST_FLAGS="-D ExperimentalMemCheck"; fi
- ctest -j2 -VV ${CTEST_FLAGS}
notifications:
email: false
prebuilt_cxx_library(
name = 'concepts',
header_namespace = 'concepts',
header_only = True,
exported_headers = subdir_glob([
('include/concepts', '**/*.hpp'),
]),
licenses = [
'LICENSE.txt',
],
)
prebuilt_cxx_library(
name = 'meta',
header_namespace = 'meta',
header_only = True,
exported_headers = subdir_glob([
('include/meta', '**/*.hpp'),
]),
licenses = [
'LICENSE.txt',
],
)
prebuilt_cxx_library(
name = 'range-v3',
header_namespace = 'range/v3',
header_only = True,
exported_headers = subdir_glob([
('include/range/v3', '**/*.hpp'),
]),
licenses = [
'LICENSE.txt',
],
visibility = [
'PUBLIC'
],
deps = [
':concepts',
':meta',
],
)
cc_library(
name = 'concepts',
hdrs = glob([
'include/concepts/**/*.hpp',
]),
includes = [
"include",
],
)
cc_library(
name = 'meta',
hdrs = glob([
'include/meta/**/*.hpp',
]),
includes = [
"include",
],
)
cc_library(
name = 'range-v3',
hdrs = glob([
'include/range/v3/**/*.hpp',
]),
visibility = ["//visibility:public"],
deps = [
':concepts',
':meta',
],
)
# Copyright Eric Niebler 2014
# Copyright Gonzalo Brito Gadeschi 2014, 2017
# Copyright Louis Dionne 2015
# Copyright Casey Carter 2016
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
cmake_minimum_required(VERSION 3.6)
get_directory_property(is_subproject PARENT_DIRECTORY)
if(NOT is_subproject)
set(is_standalone YES)
else()
set(is_standalone NO)
endif()
project(Range-v3 CXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Export compilation data-base
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
add_library(meta INTERFACE)
target_include_directories(meta INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>)
target_include_directories(meta SYSTEM INTERFACE $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>)
add_library(concepts INTERFACE)
target_include_directories(concepts INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>)
target_include_directories(concepts SYSTEM INTERFACE $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>)
target_link_libraries(concepts INTERFACE meta)
add_library(range-v3 INTERFACE)
target_include_directories(range-v3 INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>)
target_include_directories(range-v3 SYSTEM INTERFACE $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>)
target_link_libraries(range-v3 INTERFACE concepts meta)
function(rv3_add_test TESTNAME EXENAME FIRSTSOURCE)
add_executable(${EXENAME} ${FIRSTSOURCE} ${ARGN})
target_link_libraries(${EXENAME} range-v3)
add_test(${TESTNAME} ${EXENAME})
endfunction(rv3_add_test)
include(ranges_options)
include(ranges_env)
include(ranges_flags)
if(RANGE_V3_DOCS)
add_subdirectory(doc)
endif()
if(RANGE_V3_TESTS)
include(CTest)
add_subdirectory(test)
endif()
if(RANGE_V3_EXAMPLES)
add_subdirectory(example)
endif()
if(RANGE_V3_PERF)
add_subdirectory(perf)
endif()
# Add header files as sources to fix MSVS 2017 not finding source during debugging
file(GLOB_RECURSE RANGE_V3_PUBLIC_HEADERS_ABSOLUTE
"${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp")
add_custom_target(headers SOURCES ${RANGE_V3_PUBLIC_HEADERS_ABSOLUTE})
set_target_properties(headers PROPERTIES FOLDER "header")
# Test all headers
if(RANGE_V3_HEADER_CHECKS)
include(TestHeaders)
file(GLOB_RECURSE RANGE_V3_PUBLIC_HEADERS
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp")
# This header is not meant to be included directly:
list(REMOVE_ITEM RANGE_V3_PUBLIC_HEADERS std/detail/associated_types.hpp)
# Deprecated headers
if(CMAKE_CXX_COMPILER_ID STREQUAL GNU)
foreach(header ${RANGE_V3_PUBLIC_HEADERS})
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/${header}" is_deprecated
LIMIT_COUNT 1
REGEX ".*RANGES_DEPRECATED_HEADER.*")
if(is_deprecated)
list(APPEND RANGE_V3_DEPRECATED_PUBLIC_HEADERS "${header}")
endif()
endforeach()
endif()
add_header_test(test.range.v3.headers
EXCLUDE ${RANGE_V3_DEPRECATED_PUBLIC_HEADERS}
HEADERS ${RANGE_V3_PUBLIC_HEADERS})
target_link_libraries(test.range.v3.headers PRIVATE range-v3)
endif()
# Grab the range-v3 version numbers:
include(${CMAKE_CURRENT_SOURCE_DIR}/Version.cmake)
set(RANGE_V3_VERSION ${RANGE_V3_MAJOR}.${RANGE_V3_MINOR}.${RANGE_V3_PATCHLEVEL})
# Try to build a new version.hpp
configure_file(version.hpp.in include/range/v3/version.hpp @ONLY)
file(STRINGS ${CMAKE_CURRENT_BINARY_DIR}/include/range/v3/version.hpp RANGE_V3_OLD_VERSION_HPP)
file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/include/range/v3/version.hpp RANGE_V3_NEW_VERSION_HPP)
# If the new version.hpp is materially different from the one in the source
# directory, update it, commit, and tag.
if(NOT RANGE_V3_NEW_VERSION_HPP STREQUAL RANGE_V3_OLD_VERSION_HPP)
# Check that README.md and Version.cmake are the only changed file:
execute_process(
COMMAND ${GIT_EXECUTABLE} -C "${CMAKE_CURRENT_SOURCE_DIR}" status --porcelain -uno
OUTPUT_VARIABLE RANGE_V3_GIT_STATUS
OUTPUT_STRIP_TRAILING_WHITESPACE
)
string(REPLACE "\n" ";" RANGE_V3_GIT_STATUS ${RANGE_V3_GIT_STATUS})
if (NOT "x${RANGE_V3_GIT_STATUS}" STREQUAL "x M README.md; M Version.cmake")
message(FATAL_ERROR "Cannot update version.hpp: range-v3 source directory has a dirty status")
endif()
file(
COPY ${CMAKE_CURRENT_BINARY_DIR}/include/range/v3/version.hpp
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/include/range/v3
)
execute_process(
COMMAND ${GIT_EXECUTABLE} -C "${CMAKE_CURRENT_SOURCE_DIR}" add -u
)
execute_process(
COMMAND ${GIT_EXECUTABLE} -C "${CMAKE_CURRENT_SOURCE_DIR}" commit -m "${RANGE_V3_VERSION}"
)
execute_process(
COMMAND ${GIT_EXECUTABLE} -C "${CMAKE_CURRENT_SOURCE_DIR}" tag -f -a "${RANGE_V3_VERSION}" -m "${RANGE_V3_VERSION}"
)
find_program(CONAN_EXECUTABLE NAMES conan conan.exe)
if (NOT "x${CONAN_EXECUTABLE}" STREQUAL "xCONAN_EXECUTABLE-NOTFOUND")
message(STATUS "Exporting conanfile for new version")
execute_process(
COMMAND ${CONAN_EXECUTABLE} create . range-v3/${RANGE_V3_VERSION}@ericniebler/stable
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
)
endif()
message(STATUS "Version updated to ${RANGE_V3_VERSION}. Don't forget to:")
message(STATUS " git push origin <feature-branch>")
message(STATUS "and (after that is merged to master) then:")
message(STATUS " conan create ${CMAKE_CURRENT_SOURCE_DIR} range-v3/${RANGE_V3_VERSION}@ericniebler/stable")
message(STATUS " conan upload --all range-v3/${RANGE_V3_VERSION}@ericniebler/stable")
endif()
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/range-v3-config-version.cmake
VERSION ${RANGE_V3_VERSION}
COMPATIBILITY ExactVersion
)
install(TARGETS concepts meta range-v3 EXPORT range-v3-targets DESTINATION lib)
install(EXPORT range-v3-targets FILE range-v3-config.cmake DESTINATION lib/cmake/range-v3)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/range-v3-config-version.cmake
DESTINATION lib/cmake/range-v3)
install(DIRECTORY include/ DESTINATION include FILES_MATCHING PATTERN "*.hpp")
export(EXPORT range-v3-targets FILE range-v3-config.cmake)
Acknowledgements
----------------
In range-v3, I have integrated many ideas that come from other people. I would be remiss to not mention them. Many others helped either directly or indirectly in a variety of ways. In no particular order...
| Contributor | Contribution |
|-----------------------------|------|
| Jeremy Siek | Container algorithms (in Boost pre-history), Boost.Iterators |
| Thorston Ottoson | Boost.Range v1 |
| Neil Groves | Boost.Range v2 |
| David Abrahams, Thomas Witt | Boost.Iterators, Sentinels |
| Sean Parent | ASL, Projections, View / Range distinction, much Generic Program wisdom besides |
| Dietmar Kühl | Array Traits, Property Map |
| Andrew Sutton | C++ Concepts "Lite", Origin Libraries, Palo Alto Report |
| Doug Gregor | C++0x Concepts |
| Casey Carter | Co-author and Editor, Ranges TS; major code contributions |
| Gonzalo Brito Gadeschi | Many ideas, bug reports, and code contributions |
| Alexander Stepanov | STL, Generic Programming, Iterators, Elements of Programming, etc. |
| Bjarne Stroustrup | A tireless effort to add proper support for Generic Programming to C++, early support for my Ranges proposal |
| Herb Sutter | Early support for my Ranges proposal |
| The Standard C++ Foundation | A generous grant supporting my Ranges work |
An Abreviated History
--------------------
**Range v1**
I came to Boost in the early 2000's. By that time, Boost already had a Range library (Thorston Ottoson's). At this time, Boost.Range was little more that the `begin` and `end` free functions, and range-based overloads of the STL algorithms that dispatched to the iterator-based overloads in namespace `std`.
Boost also already had the Iterators library by David Abrahams and Jeremy Siek. This library had iterator adaptors like `filter_iterator` and `transform_iterator`.
**Range v2**
It seemed natural to me that the Range library and the adaptors from the Iterators library should be combined. I wrote the `filter` and `transform` range adaptors, commandeered the pipe operator (`|`) from bash for chaining, and put a rough library together called Range_ex in the Boost File Vault (which would later become the Boost Sandbox). I saw problems with my design and never finished it.
A few years later, Neil Groves picked up some of the ideas in my Range\_ex, polished them a great deal, published his own Range\_ex library, and submitted it to Boost. It became Boost.Range v2. At the time of writing (March, 2017), it is the version still shipping with Boost.
**Range v3**
In 2013, I published a blog post called ["Out Parameters, Move Semantics, and Stateful Algorithms"](http://ericniebler.com/2013/10/13/out-parameters-vs-move-semantics/) that turned my mind to ranges once again. Following that, it became clear to me that the Boost.Range library, designed for C++98, needed a facelift for the post-C++11 world. I began what I believed at the time would be a quick hack to bring Boost.Range into the modern world. I called it "Range v3", thinking it would become the third major version of the Boost.Range library. Subsequent posts detailed the evolution of my thinking as range-v3 took shape.
**Standardization**
Around this time, some big thinkers in the C++ community were working to resurrect the effort to add Concepts to C++. They published a paper ([N3351](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3351.pdf)) that would become known as the **"Palo Alto Report"** which detailed the necessary and sufficient language and library support for a concept-checked version of the Standard Template Library. The authors of the paper included Alexander Stepanov, Bjarne Stroustrup, Sean Parent, Andrew Sutton, and more. Andrew Sutton began working in earnest to realize the core language changes, an effort that became known as "Concepts Lite". (It is now the Concepts TS.)
I decided early on that Concepts Lite, or something like it, would become part of Standard C++. Recognizing that C++ would need a concept-ified Standard Library to go with the language feature, I began evolving range-v3 in that direction, eventually submitting ["Ranges for the Standard Library, Revision 1"](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4128.html) to the C++ Standardization Committee, together with Andrew Sutton and Sean Parent. The Committee approved the direction in late 2014, and so it goes...
Today (2017-03), we are very close to a final Ranges TS and are on target to integrate into Standard C++ in 2020, with *much* more to come. Stay tuned.
========================================================
Boost Software License - Version 1.0 - August 17th, 2003
========================================================
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
==============================================================================
libc++ License
==============================================================================
The libc++ library is dual licensed under both the University of Illinois
"BSD-Like" license and the MIT license. As a user of this code you may choose
to use it under either license. As a contributor, you agree to allow your code
to be used under both.
Full text of the relevant licenses is included below.
==============================================================================
University of Illinois/NCSA
Open Source License
Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
http://llvm.org/svn/llvm-project/libcxx/trunk/CREDITS.TXT
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
* Neither the names of the LLVM Team, University of Illinois at
Urbana-Champaign, nor the names of its contributors may be used to
endorse or promote products derived from this Software without specific
prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
==============================================================================
Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
http://llvm.org/svn/llvm-project/libcxx/trunk/CREDITS.TXT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
==============================================================================
Stepanov and McJones, "Elements of Programming" license
==============================================================================
// Copyright (c) 2009 Alexander Stepanov and Paul McJones
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. The authors make no
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.
//
// Algorithms from
// Elements of Programming
// by Alexander Stepanov and Paul McJones
// Addison-Wesley Professional, 2009
==============================================================================
SGI C++ Standard Template Library license
==============================================================================
// Copyright (c) 1994
// Hewlett-Packard Company
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. Hewlett-Packard Company makes no
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied warranty.
//
// Copyright (c) 1996
// Silicon Graphics Computer Systems, Inc.
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. Silicon Graphics makes no
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied warranty.
//
* Add contiguous iterator utilities. How about `is_contiguous_iterator` and `as_contiguous_range`:
```
CPP_template(typename I, typename S)(
requires RandomAccessIterator<I> &&
SizedSentinel<S, I> &&
is_contiguous_iterator<I>())
subrange<std::add_pointer_t<iter_reference_t<I>>>
as_contiguous_range(I begin, S end)
{
if(begin == end)
return {nullptr, nullptr};
else
return {addressof(*begin), addressof(*begin) + (end - begin)};
}
```
* Longer-term goals:
- Make `inplace_merge` work with forward iterators
- Make the sorting algorithms work with forward iterators
* Maybe iterators are not necessarily countable. Is there a relation between
the ability to be able to subtract two iterators to find the distance, and
with the existence of a DistanceType associated type? Think of:
- counted iterators (subtractable regardless of traversal category)
- repeat_view iterators (*not* subtractable but could be random access otherwise)
- infinite ranges (only countable with an infinite precision integer which we lack)
# To update the range-v3 version, from a *CLEAN* working directory, update the version numbers below.
# This makefile will generate a new version.hpp, *AMEND THE MOST RECENT COMMIT*, and git-tag the commit.
set(RANGE_V3_MAJOR 0)
set(RANGE_V3_MINOR 9)
set(RANGE_V3_PATCHLEVEL 0)
shallow_clone: true
image: Visual Studio 2017
platform:
- x86
- x64
configuration:
- Debug
- Release
environment:
matrix:
- CPP: latest
# - CPP: 14
cache:
- C:\ninja-1.8.2
install:
- ps: |
if (![IO.File]::Exists("C:\ninja-1.8.2\ninja.exe")) {
Start-FileDownload 'https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-win.zip'
7z x -y ninja-win.zip -oC:\ninja-1.8.2
}
$env:PATH="C:\ninja-1.8.2;$env:PATH"
- for /f "tokens=1* delims=" %%i in ('"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" %PLATFORM:x86=x64_x86%
- cmake --version
- ninja --version
- clang-cl --version
build_script:
- mkdir build && cd build
- ps: |
$env:CC='clang-cl'
$env:CXX='clang-cl'
$env:HEADER_CHECK=0
if ($env:PLATFORM -eq "x64") {
if ($env:CONFIGURATION -eq "Debug") {
$env:HEADER_CHECK=1
}
} else {
$env:CXXFLAGS='-m32'
$env:CFLAGS='-m32'
}
- cmake .. -G Ninja -Wdev -DRANGE_V3_HEADER_CHECKS=%HEADER_CHECK% -DCMAKE_BUILD_TYPE=%CONFIGURATION% -DRANGES_CXX_STD=%CPP%
- ninja -v
test_script:
- ctest -j2 --output-on-failure
deploy: off
# Copyright Louis Dionne 2013-2017
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#
#
# This CMake module provides a function generating a unit test to make sure
# that every public header can be included on its own.
#
# When a C++ library or application has many header files, it can happen that
# a header does not include all the other headers it depends on. When this is
# the case, it can happen that including that header file on its own will
# break the compilation. This CMake module generates a dummy executable
# comprised of many .cpp files, each of which includes a header file that
# is part of the public API. In other words, the executable is comprised
# of .cpp files of the form:
#
# #include <the/public/header.hpp>
#
# and then exactly one `main` function. If this succeeds to compile, it means
# that the header can be included on its own, which is what clients expect.
# Otherwise, you have a problem. Since writing these dumb unit tests by hand
# is tedious and repetitive, you can use this CMake module to automate this
# task.
# add_header_test(<target> [EXCLUDE_FROM_ALL] [EXCLUDE excludes...] HEADERS headers...)
#
# Generates header-inclusion unit tests for all the specified headers.
#
# This function creates a target which builds a dummy executable including
# each specified header file individually. If this target builds successfully,
# it means that all the specified header files can be included individually.
#
# Parameters
# ----------
# <target>:
# The name of the target to generate.
#
# HEADERS headers:
# A list of header files to generate the inclusion tests for. All headers
# in this list must be represented as relative paths from the root of the
# include directory added to the compiler's header search path. In other
# words, it should be possible to include all headers in this list as
#
# #include <${header}>
#
# For example, for a library with the following structure:
#
# project/
# doc/
# test/
# ...
# include/
# boost/
# hana.hpp
# hana/
# transform.hpp
# tuple.hpp
# pair.hpp
# ...
#
# When building the unit tests for that library, we'll add `-I project/include'
# to the compiler's arguments. The list of public headers should therefore contain
#
# boost/hana.hpp
# boost/hana/transform.hpp
# boost/hana/tuple.hpp
# boost/hana/pair.hpp
# ...
#
# Usually, all the 'public' header files of a library should be tested for
# standalone inclusion. A header is considered 'public' if a client should
# be able to include that header on its own.
#
# [EXCLUDE excludes]:
# An optional list of headers or regexes for which no unit test should be
# generated. Basically, any header in the list specified by the `HEADERS`
# argument that matches anything in `EXCLUDE` will be skipped.
#
# [EXCLUDE_FROM_ALL]:
# If provided, the generated target is excluded from the 'all' target.
#
function(add_header_test target)
cmake_parse_arguments(ARGS "EXCLUDE_FROM_ALL" # options
"" # 1 value args
"HEADERS;EXCLUDE" # multivalued args
${ARGN})
if (NOT ARGS_HEADERS)
message(FATAL_ERROR "The `HEADERS` argument must be provided.")
endif()
if (ARGS_EXCLUDE_FROM_ALL)
set(ARGS_EXCLUDE_FROM_ALL "EXCLUDE_FROM_ALL")
else()
set(ARGS_EXCLUDE_FROM_ALL "")
endif()
foreach(header ${ARGS_HEADERS})
set(skip FALSE)
foreach(exclude ${ARGS_EXCLUDE})
if (${header} MATCHES ${exclude})
set(skip TRUE)
break()
endif()
endforeach()
if (skip)
continue()
endif()
get_filename_component(filename "${header}" NAME_WE)
get_filename_component(directory "${header}" DIRECTORY)
set(source "${CMAKE_CURRENT_BINARY_DIR}/headers/${directory}/${filename}.cpp")
if (NOT EXISTS "${source}")
file(WRITE "${source}" "#include <${header}>")
endif()
list(APPEND sources "${source}")
endforeach()
set(standalone_main "${CMAKE_CURRENT_BINARY_DIR}/headers/_standalone_main.cpp")
if (NOT EXISTS "${standalone_main}")
file(WRITE "${standalone_main}" "int main() { }")
endif()
add_executable(${target}
${ARGS_EXCLUDE_FROM_ALL}
${sources}
"${CMAKE_CURRENT_BINARY_DIR}/headers/_standalone_main.cpp"
)
endfunction()
#include <new>
int main() {
struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 4) S {};
(void) ::operator new(sizeof(S), static_cast<std::align_val_t>(alignof(S)));
}
template<class>
concept bool True = true;
template<class T>
constexpr bool test(T)
{
return false;
}
template<True T>
constexpr bool test(T)
{
return true;
}
int main()
{
static_assert(::test(42), "");
}
#include <experimental/coroutine>
struct present
{
struct promise_type
{
int result;
present get_return_object() { return {*this}; }
std::experimental::suspend_never initial_suspend() { return {}; }
std::experimental::suspend_never final_suspend() { return {}; }
void return_value(int i) { result = i; }
void unhandled_exception() {}
};
promise_type& promise;
bool await_ready() const { return true; }
void await_suspend(std::experimental::coroutine_handle<>) const {}
int await_resume() const { return promise.result; }
};
present f(int n)
{
if (n < 2)
co_return 1;
else
co_return n * co_await f(n - 1);
}
int main()
{
return f(5).promise.result != 120;
}
# Copyright Louis Dionne 2015
# Copyright Gonzalo Brito Gadeschi 2015
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#
# Setup compiler flags (more can be set on a per-target basis or in
# subdirectories)
# Enable all warnings:
ranges_append_flag(RANGES_HAS_WEVERYTHING -Weverything)
ranges_append_flag(RANGES_HAS_PEDANTIC -pedantic)
ranges_append_flag(RANGES_HAS_PEDANTIC_ERRORS -pedantic-errors)
# Selectively disable those warnings that are not worth it:
ranges_append_flag(RANGES_HAS_WNO_CXX98_COMPAT -Wno-c++98-compat)
ranges_append_flag(RANGES_HAS_WNO_CXX98_COMPAT_PEDANTIC -Wno-c++98-compat-pedantic)
ranges_append_flag(RANGES_HAS_WNO_WEAK_VTABLES -Wno-weak-vtables)
ranges_append_flag(RANGES_HAS_WNO_PADDED -Wno-padded)
ranges_append_flag(RANGES_HAS_WNO_MISSING_PROTOTYPES -Wno-missing-prototypes)
ranges_append_flag(RANGES_HAS_WNO_MISSING_VARIABLE_DECLARATIONS -Wno-missing-variable-declarations)
ranges_append_flag(RANGES_HAS_WNO_DOCUMENTATION -Wno-documentation)
ranges_append_flag(RANGES_HAS_WNO_DOCUMENTATION_UNKNOWN_COMMAND -Wno-documentation-unknown-command)
ranges_append_flag(RANGES_HAS_WNO_OLD_STYLE_CAST -Wno-old-style-cast)
ranges_append_flag(RANGES_HAS_WNO_SHADOW -Wno-shadow)
if (RANGES_ENV_MACOSX)
ranges_append_flag(RANGES_HAS_WNO_GLOBAL_CONSTRUCTORS -Wno-global-constructors)
ranges_append_flag(RANGES_HAS_WNO_EXIT_TIME_DESTRUCTORS -Wno-exit-time-destructors)
endif()
if (RANGES_CXX_COMPILER_GCC)
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0")
ranges_append_flag(RANGES_HAS_WNO_STRICT_OVERFLOW -Wno-strict-overflow)
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0")
ranges_append_flag(RANGES_HAS_WNO_MISSING_FIELD_INITIALIZERS -Wno-missing-field-initializers)
endif()
elseif ((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "7.0") OR (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "7.0"))
ranges_append_flag(RANGES_HAS_WNO_NOEXCEPT_TYPE -Wno-noexcept-type)
endif()
endif()
if (RANGES_VERBOSE_BUILD)
message(STATUS "[range-v3]: test C++ flags: ${CMAKE_CXX_FLAGS}")
endif()
# Copyright Gonzalo Brito Gadeschi 2015
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#
# Detects the C++ compiler, system, build-type, etc.
include(CheckCXXCompilerFlag)
if("x${CMAKE_CXX_COMPILER_ID}" MATCHES "x.*Clang")
if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
set (RANGES_CXX_COMPILER_CLANGCL TRUE)
if (RANGES_VERBOSE_BUILD)
message(STATUS "[range-v3]: compiler is clang-cl.")
endif()
else()
set (RANGES_CXX_COMPILER_CLANG TRUE)
if (RANGES_VERBOSE_BUILD)
message(STATUS "[range-v3]: compiler is clang.")
endif()
endif()
elseif(CMAKE_COMPILER_IS_GNUCXX)
set (RANGES_CXX_COMPILER_GCC TRUE)
if (RANGES_VERBOSE_BUILD)
message(STATUS "[range-v3]: compiler is gcc.")
endif()
elseif("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
set (RANGES_CXX_COMPILER_MSVC TRUE)
if (RANGES_VERBOSE_BUILD)
message(STATUS "[range-v3]: compiler is msvc.")
endif()
else()
message(WARNING "[range-v3 warning]: unknown compiler ${CMAKE_CXX_COMPILER_ID} !")
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
set (RANGES_ENV_MACOSX TRUE)
if (RANGES_VERBOSE_BUILD)
message(STATUS "[range-v3]: system is MacOSX.")
endif()
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
set (RANGES_ENV_LINUX TRUE)
if (RANGES_VERBOSE_BUILD)
message(STATUS "[range-v3]: system is Linux.")
endif()
elseif(CMAKE_SYSTEM_NAME MATCHES "Windows")
set (RANGES_ENV_WINDOWS TRUE)
if (RANGES_VERBOSE_BUILD)
message(STATUS "[range-v3]: system is Windows.")
endif()
else()
message(WARNING "[range-v3 warning]: unknown system ${CMAKE_SYSTEM_NAME} !")
endif()
if (RANGES_CXX_COMPILER_CLANGCL OR RANGES_CXX_COMPILER_MSVC)
# Clang-CL will blow up in the standard library if compiling with less than
# C++14, and MSVC doesn't support less than C++14 at all.
if (RANGES_CXX_STD LESS 14)
set(RANGES_CXX_STD 14)
endif()
# MSVC is currently supported only in 17+ mode
if (RANGES_CXX_COMPILER_MSVC AND RANGES_CXX_STD LESS 17)
set(RANGES_CXX_STD 17)
endif()
endif()
# Build type
set(RANGES_DEBUG_BUILD FALSE)
set(RANGES_RELEASE_BUILD FALSE)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(RANGES_DEBUG_BUILD TRUE)
if (RANGES_VERBOSE_BUILD)
message(STATUS "[range-v3]: build type is debug.")
endif()
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
set(RANGES_RELEASE_BUILD TRUE)
if (RANGES_VERBOSE_BUILD)
message(STATUS "[range-v3]: build type is release.")
endif()
else()
message(WARNING "[range-v3 warning]: unknown build type, defaults to release!")
set(CMAKE_BUILD_TYPE "Release")
set(RANGES_RELEASE_BUILD TRUE)
endif()
# Find Valgrind
find_program(MEMORYCHECK_COMMAND valgrind)
if(MEMORYCHECK_COMMAND)
set(MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full")
if (RANGES_VERBOSE_BUILD)
message(STATUS "[range-v3]: valgrind found at path: ${MEMORYCHECK_COMMAND}")
endif()
else()
if (RANGES_VERBOSE_BUILD)
message(WARNING "[range-v3 warning]: valgrind not found!")
endif()
endif()
find_package(Doxygen)
find_package(Git)
# Copyright Gonzalo Brito Gadeschi 2015
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#
# CMake options
include(CMakeDependentOption)
set(RANGES_CXX_STD 14 CACHE STRING "C++ standard version.")
option(RANGES_BUILD_CALENDAR_EXAMPLE "Builds the calendar example." ON)
option(RANGES_ASAN "Run the tests using AddressSanitizer." OFF)
option(RANGES_MSAN "Run the tests using MemorySanitizer." OFF)
option(RANGES_ASSERTIONS "Enable assertions." ON)
option(RANGES_DEBUG_INFO "Include debug information in the binaries." ON)
option(RANGES_MODULES "Enables use of Clang modules (experimental)." OFF)
option(RANGES_NATIVE "Enables -march/-mtune=native." ON)
option(RANGES_VERBOSE_BUILD "Enables debug output from CMake." OFF)
option(RANGES_LLVM_POLLY "Enables LLVM Polly." OFF)
option(RANGES_PREFER_REAL_CONCEPTS
"Use real concepts instead of emulation if the compiler supports it"
ON)
option(RANGES_DEEP_STL_INTEGRATION
"Hijacks the primary std::iterator_traits template to emulate the C++20 std::ranges:: behavior."
OFF)
option(RANGE_V3_HEADER_CHECKS
"Build the Range-v3 header checks and integrate with ctest"
OFF)
set(RANGES_INLINE_THRESHOLD -1 CACHE STRING "Force a specific inlining threshold.")
# Enable verbose configure when passing -Wdev to CMake
if (DEFINED CMAKE_SUPPRESS_DEVELOPER_WARNINGS AND
NOT CMAKE_SUPPRESS_DEVELOPER_WARNINGS)
set(RANGES_VERBOSE_BUILD ON)
endif()
if (RANGES_VERBOSE_BUILD)
message(STATUS "[range-v3]: verbose build enabled.")
endif()
CMAKE_DEPENDENT_OPTION(RANGE_V3_TESTS
"Build the Range-v3 tests and integrate with ctest"
ON "${is_standalone}" OFF)
CMAKE_DEPENDENT_OPTION(RANGE_V3_EXAMPLES
"Build the Range-v3 examples and integrate with ctest"
ON "${is_standalone}" OFF)
CMAKE_DEPENDENT_OPTION(RANGE_V3_PERF
"Build the Range-v3 performance benchmarks"
ON "${is_standalone}" OFF)
CMAKE_DEPENDENT_OPTION(RANGE_V3_DOCS
"Build the Range-v3 documentation"
ON "${is_standalone}" OFF)
mark_as_advanced(RANGE_V3_PERF)
# CMake files overview:
- `ranges_options.cmake`: All options to configure the library.
- `ranges_env.cmake`: Detects the environment: operating system, compiler, build-type, ...
- `ranges_flags.cmake`: Sets up all compiler flags.
# Range v3 library
#
# Copyright Luis Martinez de Bartolome Izquierdo 2016
#
# Use, modification and distribution is subject to the
# Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
#
# Project home: https://github.com/ericniebler/range-v3
#
from conans import ConanFile, CMake
class Rangev3Conan(ConanFile):
name = "range-v3"
version = "v1.0-beta"
license = "Boost Software License - Version 1.0 - August 17th, 2003"
url = "https://github.com/ericniebler/range-v3"
description = """Experimental range library for C++11/14/17"""
settings = "compiler", "arch"
exports_sources = "include*", "LICENSE.txt", "CMakeLists.txt", "cmake/*", "Version.cmake", "version.hpp.in"
build_policy = "missing"
def build(self):
pass
def package(self):
cmake = CMake(self)
cmake.definitions["RANGE_V3_TESTS"] = "OFF"
cmake.definitions["RANGE_V3_EXAMPLES"] = "OFF"
cmake.definitions["RANGE_V3_PERF"] = "OFF"
cmake.definitions["RANGE_V3_DOCS"] = "OFF"
cmake.definitions["RANGE_V3_HEADER_CHECKS"] = "OFF"
cmake.configure()
cmake.install()
self.copy("LICENSE.txt", dst="licenses", ignore_case=True, keep_path=False)
def package_info(self):
self.info.header_only()
#=============================================================================
# Setup the documentation
#=============================================================================
if (NOT DOXYGEN_FOUND)
message(STATUS
"Doxygen not found; the 'doc' and 'gh-pages.{clean,copy,update}' targets "
"will be unavailable.")
return()
endif()
set(CMAKE_FOLDER "doc")
configure_file(Doxyfile.in Doxyfile @ONLY)
add_custom_target(doc.check
COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
COMMENT "Running Doxygen to validate the documentation"
VERBATIM
)
set_target_properties(doc.check
PROPERTIES FOLDER ${CMAKE_FOLDER}
)
# if (NOT TARGET benchmarks)
# message(STATUS
# "The 'benchmarks' target is not available; the 'doc' and "
# "'gh-pages.{clean,copy,update}' targets will be unavailable. "
# "The 'doc.check' target can still be used to generate the "
# "documentation to check for errors/warnings.")
# return()
# endif()
add_custom_target(doc
COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
COMMENT "Generating API documentation with Doxygen"
# DEPENDS benchmarks
VERBATIM
)
set_target_properties(doc
PROPERTIES FOLDER ${CMAKE_FOLDER}
)
if (NOT GIT_FOUND)
message(STATUS
"Git was not found; the 'gh-pages.{clean,copy,update}' targets "
"will be unavailable.")
return()
endif()
add_custom_target(gh-pages.clean
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/clean-gh-pages.cmake
COMMAND ${CMAKE_COMMAND} -E remove_directory search
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/gh-pages
COMMENT "Cleaning up doc/gh-pages"
VERBATIM
)
set_target_properties(gh-pages.clean
PROPERTIES FOLDER ${CMAKE_FOLDER}
)
add_custom_target(gh-pages.copy
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/html ${CMAKE_CURRENT_LIST_DIR}/gh-pages
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/gh-pages
COMMENT "Copying the documentation from ${CMAKE_CURRENT_BINARY_DIR}/html to doc/gh-pages"
DEPENDS doc gh-pages.clean
VERBATIM
)
set_target_properties(gh-pages.copy
PROPERTIES FOLDER ${CMAKE_FOLDER}
)
execute_process(
COMMAND ${GIT_EXECUTABLE} -C ${CMAKE_SOURCE_DIR} rev-parse --short HEAD
OUTPUT_VARIABLE RANGE_V3_GIT_SHORT_SHA
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_custom_target(gh-pages.update
COMMAND ${GIT_EXECUTABLE} add --all .
COMMAND ${GIT_EXECUTABLE} commit -m "Update to ${RANGE_V3_GIT_SHORT_SHA}"
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/gh-pages
COMMENT "Updating the gh-pages branch with freshly built documentation"
DEPENDS gh-pages.copy
VERBATIM
)
set_target_properties(gh-pages.update
PROPERTIES FOLDER ${CMAKE_FOLDER}
)
PROJECT_NAME = "Range-v3"
PROJECT_BRIEF = "Range algorithms, views, and actions for the Standard Library"
PROJECT_LOGO =
PROJECT_NUMBER =
STRIP_FROM_PATH = @Range-v3_SOURCE_DIR@/include
BUILTIN_STL_SUPPORT = YES
STRIP_FROM_INC_PATH = @Range-v3_SOURCE_DIR@/include
ALIASES =
ENABLED_SECTIONS =
# Resources
OUTPUT_DIRECTORY =
INPUT = @Range-v3_SOURCE_DIR@/include \
@Range-v3_SOURCE_DIR@/doc/index.md
FILE_PATTERNS = *.hpp *.md
RECURSIVE = YES
EXCLUDE = @Range-v3_SOURCE_DIR@/include/range/v3/detail \
@Range-v3_SOURCE_DIR@/include/range/v3/algorithm/aux_ \
@Range-v3_SOURCE_DIR@/include/range/v3/utility/safe_int.hpp
EXAMPLE_PATH = @Range-v3_SOURCE_DIR@/example \
@Range-v3_SOURCE_DIR@/test
EXAMPLE_RECURSIVE = YES
IMAGE_PATH = @Range-v3_BINARY_DIR@/image
WARN_IF_UNDOCUMENTED = NO
SHOW_GROUPED_MEMB_INC = YES
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
JAVADOC_AUTOBRIEF = YES
QT_AUTOBRIEF = YES
MULTILINE_CPP_IS_BRIEF = YES
INHERIT_DOCS = NO
SEPARATE_MEMBER_PAGES = NO
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = NO
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS = NO
# Generated formats
GENERATE_HTML = YES
GENERATE_LATEX = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST = YES
SHOW_USED_FILES = NO
SHOW_FILES = YES
SHOW_NAMESPACES = YES
LAYOUT_FILE = @Range-v3_SOURCE_DIR@/doc/layout.xml
CLASS_DIAGRAMS = YES
HAVE_DOT = NO
HIDE_UNDOC_RELATIONS = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = NO
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = NO
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = YES
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = YES
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 1
# Preprocessing
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH = @Range-v3_SOURCE_DIR@/include
INCLUDE_FILE_PATTERNS =
PREDEFINED = RANGES_DOXYGEN_INVOKED=1 \
META_DOXYGEN_INVOKED=1 \
CPP_DOXYGEN_INVOKED=1 \
"RANGES_INLINE_VARIABLE(T,N)=inline constexpr T N{};"
SKIP_FUNCTION_MACROS = NO
# Source browsing
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = NO
# CLANG_ASSISTED_PARSING = NO
# CLANG_OPTIONS =
# HTML output
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_EXTRA_STYLESHEET =
HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 75 # 0 - 359
HTML_COLORSTYLE_SAT = 100 # 0 - 255
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = NO
HTML_DYNAMIC_SECTIONS = YES
HTML_INDEX_NUM_ENTRIES = 0 # Fully expand trees in the Indexes by default
DISABLE_INDEX = YES
GENERATE_TREEVIEW = YES
TREEVIEW_WIDTH = 270
EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
SEARCHENGINE = YES
# Mathjax (HTML only)
USE_MATHJAX = NO
MATHJAX_FORMAT = HTML-CSS
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
MATHJAX_EXTENSIONS =
MATHJAX_CODEFILE =
FILE(GLOB gh_files "*.html" "*.js" "*.css" "*.png")
IF( gh_files )
execute_process( COMMAND ${CMAKE_COMMAND} -E remove ${gh_files} )
ENDIF()
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.8.7 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes"
title="Reference"
intro="
The reference documentation is split into logical modules, as documented in
the user manual."/>
<tab type="usergroup" visible="yes" title="Indexes">
<tab type="classmembers" visible="yes"
title="Methods"
intro="
This is an index of all the methods with links to the
corresponding documentation."/>
<tab type="classlist" visible="yes"
title="Classes"
intro="
This is an index of all the classes in the library with links to the
corresponding documentation."/>
<tab type="filelist" visible="yes"
title="Files"
intro=""/>
</tab>
<!-- We don't use what's below -->
<tab type="namespaces" visible="no" title="">
<tab type="namespacelist" visible="no" title="" intro=""/>
<tab type="namespacemembers" visible="no" title="" intro=""/>
</tab>
<tab type="examples" visible="no" title="" intro=""/>
<tab type="classes" visible="no" title="">
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="no" title="" intro=""/>
</tab>
<tab type="files" visible="no" title="Files">
<tab type="globals" visible="no" title="Globals" intro=""/>
</tab>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="no"/>
<detaileddescription title="Description"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<memberdecl>
<related title="Synopsis of methods" subtitle=" "/>
<nestedclasses visible="yes" title="Instances and minimal complete definitions"/>
<friends title=""/>
<membergroups visible="yes"/>
<!-- We don't use what's below -->
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
</memberdecl>
<memberdef>
<related title="Methods"/>
<functions title=""/>
<variables title=""/>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<!-- This is not for C++ -->
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<classes visible="yes" title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="no"/>
<detaileddescription title="Description"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>
This source diff could not be displayed because it is too large. You can view the blob instead.
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="607">
<tr>
<td width="172" align="left" valign="top">Document number:</td>
<td width="435">
<span style="background-color: #FFFF00">D4128</span>=yy-nnnn
</td>
</tr>
<tr>
<td width="172" align="left" valign="top">Date:</td>
<td width="435">2014-10-10</td>
</tr>
<tr>
<td width="172" align="left" valign="top">Project:</td>
<td width="435">Programming Language C++, Library Working Group</td>
</tr>
<tr>
<td width="172" align="left" valign="top">Reply-to:</td>
<td width="435">
Eric Niebler &lt;<a href="mailto:eniebler@boost.org">eniebler@boost.org</a>&gt;,<br/>
Sean Parent &lt;<a href="mailto:sparent@adobe.com">sparent@adobe.com</a>&gt;,<br/>
Andrew Sutton &lt;<a href="mailto:andrew.n.sutton@gmail.com">andrew.n.sutton@gmail.com</a>&gt;
</td>
</tr>
</table>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"$if(lang)$ lang="$lang$" xml:lang="$lang$"$endif$>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
$for(author-meta)$
<meta name="author" content="$author-meta$" />
$endfor$
$if(date-meta)$
<meta name="date" content="$date-meta$" />
$endif$
<title>$if(title-prefix)$$title-prefix$ - $endif$$pagetitle$</title>
<style type="text/css">code{white-space: pre;}</style>
$if(quotes)$
<style type="text/css">q { quotes: "“" "”" "‘" "’"; }</style>
$endif$
$if(highlighting-css)$
<style type="text/css">
$highlighting-css$
</style>
$endif$
$for(css)$
<link rel="stylesheet" href="$css$" $if(html5)$$else$type="text/css" $endif$/>
$endfor$
$if(math)$
$math$
$endif$
$for(header-includes)$
$header-includes$
$endfor$
</head>
<body>
$for(include-before)$
$include-before$
$endfor$
$if(title)$
<div id="$idprefix$header">
<h1 class="title">$title$</h1>
$if(subtitle)$
<h1 class="subtitle">$subtitle$</h1>
$endif$
$for(author)$
<h2 class="author">$author$</h2>
$endfor$
$if(date)$
<h3 class="date">$date$</h3>
$endif$
</div>
$endif$
<blockquote>
<p>“A beginning is the time for taking the most delicate care that the balances are correct.”</p>
<p>
– Frank Herbert, <em>Dune</em>
</p>
</blockquote>
$if(toc)$
<div id="$idprefix$TOC">
$toc$
</div>
$endif$
$body$
$for(include-after)$
$include-after$
$endfor$
</body>
</html>
pandoc -f markdown_github+yaml_metadata_block+citations -t html -o D4128.html --filter pandoc-citeproc --csl=acm-sig-proceedings.csl --number-sections --toc -s -S --template=pandoc-template --include-before-body=header.html D4128.md
{
AccessModifierOffset: -4,
AlignEscapedNewlinesLeft: true,
AlignTrailingComments: false,
AllowAllParametersOfDeclarationOnNextLine: false,
AllowShortBlocksOnASingleLine: true,
AllowShortFunctionsOnASingleLine: Empty,
AllowShortIfStatementsOnASingleLine: false,
AllowShortLoopsOnASingleLine: false,
AlwaysBreakBeforeMultilineStrings: true,
AlwaysBreakAfterReturnType: None,
AlwaysBreakTemplateDeclarations: true,
BasedOnStyle: Mozilla,
BinPackParameters: true,
BraceWrapping: {
AfterClass: true,
AfterControlStatement: true,
AfterEnum: true,
AfterFunction: true,
AfterNamespace: true,
AfterStruct: true,
AfterUnion: true,
AfterExternBlock: true,
BeforeCatch: true,
BeforeElse: true,
IndentBraces: false,
SplitEmptyFunction: false,
SplitEmptyRecord: false,
SplitEmptyNamespace: true,
},
BreakBeforeBinaryOperators: false,
BreakBeforeBraces: Custom,
BreakBeforeTernaryOperators: true,
BreakConstructorInitializersBeforeComma: false,
ColumnLimit: 80,
ConstructorInitializerAllOnOneLineOrOnePerLine: false,
ConstructorInitializerIndentWidth: 2,
ContinuationIndentWidth: 4,
Cpp11BracedListStyle: true,
DerivePointerBinding: true,
ExperimentalAutoDetectBinPacking: false,
IndentCaseLabels: true,
IndentFunctionDeclarationAfterType: false,
IndentWidth: 4,
KeepEmptyLinesAtTheStartOfBlocks: true,
Language: Cpp,
MaxEmptyLinesToKeep: 1,
NamespaceIndentation: All,
PenaltyBreakBeforeFirstCallParameter: 10,
PenaltyReturnTypeOnItsOwnLine: 1000000,
PointerBindsToType: true,
SpaceAfterControlStatementKeyword: false,
SpaceBeforeAssignmentOperators: true,
SpaceBeforeParens: Never,
SpaceInEmptyParentheses: false,
SpacesBeforeTrailingComments: 1,
SpacesInAngles: false,
SpacesInCStyleCastParentheses: false,
SpacesInParentheses: false,
Standard: Cpp11,
TabWidth: 4,
UseTab: Never,
}
cxx_binary(
name = 'comprehensions',
srcs = [
'comprehensions.cpp',
],
deps = [
'//:range-v3',
],
compiler_flags = [
'-std=c++14',
],
)
cxx_binary(
name = 'count_if',
srcs = [
'count_if.cpp',
],
deps = [
'//:range-v3',
],
compiler_flags = [
'-std=c++14',
],
)
cxx_binary(
name = 'count',
srcs = [
'count.cpp',
],
deps = [
'//:range-v3',
],
compiler_flags = [
'-std=c++14',
],
)
cxx_binary(
name = 'find',
srcs = [
'find.cpp',
],
deps = [
'//:range-v3',
],
compiler_flags = [
'-std=c++14',
],
)
cxx_binary(
name = 'for_each_assoc',
srcs = [
'for_each_assoc.cpp',
],
deps = [
'//:range-v3',
],
compiler_flags = [
'-std=c++14',
],
)
cxx_binary(
name = 'for_each_sequence',
srcs = [
'for_each_sequence.cpp',
],
deps = [
'//:range-v3',
],
compiler_flags = [
'-std=c++14',
],
)
cxx_binary(
name = 'hello',
srcs = [
'hello.cpp',
],
deps = [
'//:range-v3',
],
compiler_flags = [
'-std=c++14',
],
)
cxx_binary(
name = 'is_sorted',
srcs = [
'is_sorted.cpp',
],
deps = [
'//:range-v3',
],
compiler_flags = [
'-std=c++14',
],
)
set(CMAKE_FOLDER "example")
# examples use a less draconian set of compiler warnings
ranges_append_flag(RANGES_HAS_WNO_MISSING_BRACES -Wno-missing-braces)
ranges_append_flag(RANGES_HAS_WNO_SHORTEN_64_TO_32 -Wno-shorten-64-to-32)
ranges_append_flag(RANGES_HAS_WNO_GLOBAL_CONSTRUCTORS -Wno-global-constructors)
rv3_add_test(example.comprehensions comprehensions comprehensions.cpp)
rv3_add_test(example.hello hello hello.cpp)
rv3_add_test(example.count count count.cpp)
rv3_add_test(example.count_if count_if count_if.cpp)
rv3_add_test(example.any_all_none_of any_all_none_of any_all_none_of.cpp)
rv3_add_test(example.for_each_sequence for_each_sequence for_each_sequence.cpp)
rv3_add_test(example.for_each_assoc for_each_assoc for_each_assoc.cpp)
rv3_add_test(example.is_sorted is_sorted is_sorted.cpp)
rv3_add_test(example.find find find.cpp)
# Guarded with a variable because the calendar example causes gcc to puke.
if(RANGES_BUILD_CALENDAR_EXAMPLE)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED OFF)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.59.0 COMPONENTS date_time program_options)
if (Boost_FOUND)
add_executable(calendar calendar.cpp)
target_include_directories(calendar SYSTEM PRIVATE ${Boost_INCLUDE_DIRS})
target_link_libraries(calendar range-v3 ${Boost_LIBRARIES})
message(STATUS "boost: ${Boost_LIBRARY_DIRS}")
target_compile_definitions(calendar PRIVATE BOOST_NO_AUTO_PTR)
target_compile_options(calendar PRIVATE -std=gnu++14)
set_target_properties(calendar PROPERTIES LINK_FLAGS "-L${Boost_LIBRARY_DIRS}")
endif()
endif()
// Range v3 library
//
// Copyright Jeff Garland 2017
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
//[any_all_none_of]]
// Demonstrates any_of, all_of, none_of
// output
// vector: [6,2,3,4,5,6]
// vector any_of is_six: true
// vector all_of is_six: false
// vector none_of is_six: false
#include <range/v3/algorithm/all_of.hpp>
#include <range/v3/algorithm/any_of.hpp>
#include <range/v3/algorithm/for_each.hpp>
#include <range/v3/algorithm/none_of.hpp>
#include <range/v3/view/all.hpp>
#include <iostream>
#include <vector>
using std::cout;
auto is_six = [](int i) { return i == 6; };
int
main()
{
std::vector<int> v{6, 2, 3, 4, 5, 6};
cout << std::boolalpha;
cout << "vector: " << ranges::view::all(v) << '\n';
cout << "vector any_of is_six: " << ranges::any_of(v, is_six) << '\n';
cout << "vector all_of is_six: " << ranges::all_of(v, is_six) << '\n';
cout << "vector none_of is_six: " << ranges::none_of(v, is_six) << '\n';
}
//[any_all_none_of]]
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#include <chrono>
#include <iostream>
#include <range/v3/all.hpp>
using namespace ranges;
int
main()
{
// Define an infinite range containing all the Pythagorean triples:
auto triples = view::for_each(view::iota(1), [](int z) {
return view::for_each(view::iota(1, z + 1), [=](int x) {
return view::for_each(view::iota(x, z + 1), [=](int y) {
return yield_if(x * x + y * y == z * z,
std::make_tuple(x, y, z));
});
});
});
//// This alternate syntax also works:
// auto triples = iota(1) >>= [] (int z) { return
// iota(1, z+1) >>= [=](int x) { return
// iota(x, z+1) >>= [=](int y) { return
// yield_if(x*x + y*y == z*z,
// std::make_tuple(x, y, z)); };}; };
// Display the first 100 triples
RANGES_FOR(auto triple, triples | view::take(100))
{
std::cout << '(' << std::get<0>(triple) << ',' << std::get<1>(triple)
<< ',' << std::get<2>(triple) << ')' << '\n';
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Benchmark Code
////////////////////////////////////////////////////////////////////////////////////////////////////
class timer
{
private:
std::chrono::high_resolution_clock::time_point start_;
public:
timer()
{
reset();
}
void reset()
{
start_ = std::chrono::high_resolution_clock::now();
}
std::chrono::milliseconds elapsed() const
{
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now() - start_);
}
friend std::ostream &operator<<(std::ostream &sout, timer const &t)
{
return sout << t.elapsed().count() << "ms";
}
};
void
benchmark()
{
// Define an infinite range containing all the Pythagorean triples:
auto triples = view::for_each(view::iota(1), [](int z) {
return view::for_each(view::iota(1, z + 1), [=](int x) {
return view::for_each(view::iota(x, z + 1), [=](int y) {
return yield_if(x * x + y * y == z * z,
std::make_tuple(x, y, z));
});
});
});
static constexpr int max_triples = 3000;
timer t;
int result = 0;
RANGES_FOR(auto triple, triples | view::take(max_triples))
{
int i, j, k;
std::tie(i, j, k) = triple;
result += (i + j + k);
}
std::cout << t << '\n';
std::cout << result << '\n';
result = 0;
int found = 0;
t.reset();
for(int z = 1;; ++z)
{
for(int x = 1; x <= z; ++x)
{
for(int y = x; y <= z; ++y)
{
if(x * x + y * y == z * z)
{
result += (x + y + z);
++found;
if(found == max_triples)
goto done;
}
}
}
}
done:
std::cout << t << '\n';
std::cout << result << '\n';
}
// Range v3 library
//
// Copyright Jeff Garland 2017
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
///[count]
// This example demonstrates counting the number of
// elements that match a given value.
// output...
// vector: 2
// array: 2
#include <iostream>
#include <range/v3/algorithm/count.hpp> // specific includes
#include <vector>
using std::cout;
int
main()
{
std::vector<int> v{6, 2, 3, 4, 5, 6};
// note the count return is a numeric type
// like int or long -- auto below make sure
// it matches the implementation
auto c = ranges::count(v, 6);
cout << "vector: " << c << '\n';
std::array<int, 6> a{6, 2, 3, 4, 5, 6};
c = ranges::count(a, 6);
cout << "array: " << c << '\n';
}
///[count]
// Range v3 library
//
// Copyright Jeff Garland 2017
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
///[count_if]
// This example counts element of a range that match a supplied predicate.
// output
// vector: 2
// array: 2
#include <array>
#include <iostream>
#include <range/v3/algorithm/count_if.hpp> // specific includes
#include <vector>
using std::cout;
auto is_six = [](int i) -> bool { return i == 6; };
int
main()
{
std::vector<int> v{6, 2, 3, 4, 5, 6};
auto c = ranges::count_if(v, is_six);
cout << "vector: " << c << '\n'; // 2
std::array<int, 6> a{6, 2, 3, 4, 5, 6};
c = ranges::count_if(a, is_six);
cout << "array: " << c << '\n'; // 2
}
///[count_if]
// Range v3 library
//
// Copyright Jeff Garland 2017
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
///[find]
// vector: *i: 6
// didn't find 10
// *i: 6
// *i: 2
// *i after ++ (2 expected): 2
// array: *i: 6
// list: *i: 6
// fwd_list: *i: 4
// deque: *i: 6
#include <array>
#include <deque>
#include <forward_list>
#include <iostream>
#include <list>
#include <range/v3/all.hpp>
#include <vector>
using std::cout;
auto is_six = [](int i) -> bool { return i == 6; };
int
main()
{
cout << "vector: ";
std::vector<int> v{6, 2, 6, 4, 6, 1};
{
auto i = ranges::find(v, 6); // 1 2 3 4 5 6
cout << "*i: " << *i << '\n';
}
{
auto i = ranges::find(v, 10); // 1 2 3 4 5 6
if(i == ranges::end(v))
{
cout << "didn't find 10\n";
}
}
{
auto i = ranges::find_if(v, is_six);
if(i != ranges::end(v))
{
cout << "*i: " << *i << '\n';
}
}
{
auto i = ranges::find_if_not(v, is_six);
if(i != ranges::end(v))
{
cout << "*i: " << *i << '\n';
}
}
{
auto i = ranges::find(v, 6);
i++;
if(i != ranges::end(v))
{
cout << "*i after ++ (2 expected): " << *i;
}
}
cout << "\narray: ";
std::array<int, 6> a{6, 2, 3, 4, 5, 1};
{
auto i = ranges::find(a, 6);
if(i != ranges::end(a))
{
cout << "*i: " << *i;
}
}
cout << "\nlist: ";
std::list<int> li{6, 2, 3, 4, 5, 1};
{
auto i = ranges::find(li, 6);
if(i != ranges::end(li))
{
cout << "*i: " << *i;
}
}
cout << "\nfwd_list: ";
std::forward_list<int> fl{6, 2, 3, 4, 5, 1};
{
auto i = ranges::find(fl, 4);
if(i != ranges::end(fl))
{
cout << "*i: " << *i;
}
}
cout << "\ndeque: ";
std::deque<int> d{6, 2, 3, 4, 5, 1};
{
auto i = ranges::find(d, 6);
if(i != ranges::end(d))
{
cout << "*i: " << *i;
}
}
cout << '\n';
}
///[find]
// Range v3 library
//
// Copyright Jeff Garland 2017
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
///[for_each_assoc]
// for_each with associative containers
// output
// set: 1 2 3 4 5 6
// map: one:1 three:3 two:2
// unordered_map: three:3 one:1 two:2
// unordered_set: 6 5 4 3 2 1
#include <iostream>
#include <map>
#include <range/v3/algorithm/for_each.hpp>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
using std::cout;
using std::string;
auto print = [](int i) { cout << i << ' '; };
// must take a pair for map types
auto printm = [](std::pair<string, int> p) {
cout << p.first << ":" << p.second << ' ';
};
int
main()
{
cout << "set: ";
std::set<int> si{1, 2, 3, 4, 5, 6};
ranges::for_each(si, print);
cout << "\nmap: ";
std::map<string, int> msi{{"one", 1}, {"two", 2}, {"three", 3}};
ranges::for_each(msi, printm);
cout << "\nunordered map: ";
std::unordered_map<string, int> umsi{{"one", 1}, {"two", 2}, {"three", 3}};
ranges::for_each(umsi, printm);
cout << "\nunordered set: ";
std::unordered_set<int> usi{1, 2, 3, 4, 5, 6};
ranges::for_each(usi, print);
cout << '\n';
}
///[for_each_assoc]
// Range v3 library
//
// Copyright Jeff Garland 2017
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
///[for_each_sequence]
// Use the for_each to print from various containers
// output
// vector: 1 2 3 4 5 6
// array: 1 2 3 4 5 6
// list: 1 2 3 4 5 6
// fwd_list: 1 2 3 4 5 6
// deque: 1 2 3 4 5 6
#include <array>
#include <deque>
#include <forward_list>
#include <iostream>
#include <list>
#include <queue>
#include <range/v3/algorithm/for_each.hpp> // specific includes
#include <stack>
#include <vector>
using std::cout;
auto print = [](int i) { cout << i << ' '; };
int
main()
{
cout << "vector: ";
std::vector<int> v{1, 2, 3, 4, 5, 6};
ranges::for_each(v, print); // 1 2 3 4 5 6
cout << "\narray: ";
std::array<int, 6> a{1, 2, 3, 4, 5, 6};
ranges::for_each(a, print);
cout << "\nlist: ";
std::list<int> ll{1, 2, 3, 4, 5, 6};
ranges::for_each(ll, print);
cout << "\nfwd_list: ";
std::forward_list<int> fl{1, 2, 3, 4, 5, 6};
ranges::for_each(fl, print);
cout << "\ndeque: ";
std::deque<int> d{1, 2, 3, 4, 5, 6};
ranges::for_each(d, print);
cout << '\n';
}
///[for_each_sequence]
// Range v3 library
//
// Copyright Jeff Garland 2017
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
///[hello]
#include <iostream>
#include <range/v3/all.hpp> // get everything
#include <string>
using std::cout;
int
main()
{
std::string s{"hello"};
// output: h e l l o
ranges::for_each(s, [](char c) { cout << c << ' '; });
cout << '\n';
}
///[hello]
// Range v3 library
//
// Copyright Jeff Garland 2017
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
///[is_sorted]
// Check if a container is sorted
// output
// vector: true
// array: false
#include <array>
#include <iostream>
#include <range/v3/algorithm/is_sorted.hpp> // specific includes
#include <vector>
using std::cout;
int
main()
{
cout << std::boolalpha;
std::vector<int> v{1, 2, 3, 4, 5, 6};
cout << "vector: " << ranges::is_sorted(v) << '\n';
std::array<int, 6> a{6, 2, 3, 4, 5, 6};
cout << "array: " << ranges::is_sorted(a) << '\n';
}
///[is_sorted]
This source diff could not be displayed because it is too large. You can view the blob instead.
/// \file meta_fwd.hpp Forward declarations
//
// Meta library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/meta
//
#ifndef META_FWD_HPP
#define META_FWD_HPP
#include <type_traits>
#include <utility>
#ifdef __clang__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-variable-declarations"
#endif
#define META_CXX_STD_14 201402L
#define META_CXX_STD_17 201703L
#if defined(_MSVC_LANG) && _MSVC_LANG > __cplusplus // Older clangs define _MSVC_LANG < __cplusplus
#define META_CXX_VER _MSVC_LANG
#else
#define META_CXX_VER __cplusplus
#endif
#if defined(__apple_build_version__) || defined(__clang__)
#if defined(__apple_build_version__) || (defined(__clang__) && __clang_major__ < 6)
#define META_WORKAROUND_LLVM_28385 // https://llvm.org/bugs/show_bug.cgi?id=28385
#endif
#elif defined(_MSC_VER)
#define META_HAS_MAKE_INTEGER_SEQ 1
#if _MSC_VER < 1920
#define META_WORKAROUND_MSVC_702792 // Bogus C4018 comparing constant expressions with dependent type
#define META_WORKAROUND_MSVC_703656 // ICE with pack expansion inside decltype in alias template
#endif
#if _MSC_VER < 1921
#define META_WORKAROUND_MSVC_756112 // fold expression + alias templates in template argument
#endif
#elif defined(__GNUC__)
#define META_WORKAROUND_GCC_86356 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86356
#if __GNUC__ < 8
#define META_WORKAROUND_GCC_UNKNOWN1 // Older GCCs don't like fold + debug + -march=native
#endif
#if __GNUC__ == 5 && __GNUC_MINOR__ == 1
#define META_WORKAROUND_GCC_66405 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66405
#endif
#if __GNUC__ < 5
#define META_WORKAROUND_CWG_1558 // https://wg21.link/cwg1558
#endif
#endif
#ifndef META_CXX_VARIABLE_TEMPLATES
#ifdef __cpp_variable_templates
#define META_CXX_VARIABLE_TEMPLATES __cpp_variable_templates
#else
#define META_CXX_VARIABLE_TEMPLATES (META_CXX_VER >= META_CXX_STD_14)
#endif
#endif
#ifndef META_CXX_INLINE_VARIABLES
#ifdef __cpp_inline_variables
#define META_CXX_INLINE_VARIABLES __cpp_inline_variables
#else
#define META_CXX_INLINE_VARIABLES (META_CXX_VER >= META_CXX_STD_17)
#endif
#endif
#ifndef META_INLINE_VAR
#if META_CXX_INLINE_VARIABLES
#define META_INLINE_VAR inline
#else
#define META_INLINE_VAR
#endif
#endif
#ifndef META_CXX_INTEGER_SEQUENCE
#ifdef __cpp_lib_integer_sequence
#define META_CXX_INTEGER_SEQUENCE __cpp_lib_integer_sequence
#else
#define META_CXX_INTEGER_SEQUENCE (META_CXX_VER >= META_CXX_STD_14)
#endif
#endif
#ifndef META_HAS_MAKE_INTEGER_SEQ
#ifdef __has_builtin
#if __has_builtin(__make_integer_seq)
#define META_HAS_MAKE_INTEGER_SEQ 1
#endif
#endif
#endif
#ifndef META_HAS_MAKE_INTEGER_SEQ
#define META_HAS_MAKE_INTEGER_SEQ 0
#endif
#ifndef META_HAS_TYPE_PACK_ELEMENT
#ifdef __has_builtin
#if __has_builtin(__type_pack_element)
#define META_HAS_TYPE_PACK_ELEMENT 1
#endif
#endif
#endif
#ifndef META_HAS_TYPE_PACK_ELEMENT
#define META_HAS_TYPE_PACK_ELEMENT 0
#endif
#if !defined(META_DEPRECATED) && !defined(META_DISABLE_DEPRECATED_WARNINGS)
#if defined(__cpp_attribute_deprecated) || META_CXX_VER >= META_CXX_STD_14
#define META_DEPRECATED(...) [[deprecated(__VA_ARGS__)]]
#elif defined(__clang__) || defined(__GNUC__)
#define META_DEPRECATED(...) __attribute__((deprecated(__VA_ARGS__)))
#endif
#endif
#ifndef META_DEPRECATED
#define META_DEPRECATED(...)
#endif
#ifndef META_CXX_FOLD_EXPRESSIONS
#ifdef __cpp_fold_expressions
#define META_CXX_FOLD_EXPRESSIONS __cpp_fold_expressions
#else
#define META_CXX_FOLD_EXPRESSIONS (META_CXX_VER >= META_CXX_STD_17)
#endif
#endif
#if META_CXX_FOLD_EXPRESSIONS
#if !META_CXX_VARIABLE_TEMPLATES
#error Fold expressions, but no variable templates?
#endif
#endif
#if defined(__cpp_concepts) && __cpp_concepts > 0
#if !META_CXX_VARIABLE_TEMPLATES
#error Concepts, but no variable templates?
#endif
#if __cpp_concepts <= 201507L
#define META_CONCEPT concept bool
// TS concepts subsumption barrier for atomic expressions
#define META_CONCEPT_BARRIER(...) ::meta::detail::bool_<__VA_ARGS__>
#else
#define META_CONCEPT concept
#define META_CONCEPT_BARRIER(...) __VA_ARGS__
#endif
#define META_TYPE_CONSTRAINT(...) __VA_ARGS__
#else
#define META_TYPE_CONSTRAINT(...) typename
#endif
#if (defined(__cpp_lib_type_trait_variable_templates) && \
__cpp_lib_type_trait_variable_templates > 0)
#define META_CXX_TRAIT_VARIABLE_TEMPLATES 1
#else
#define META_CXX_TRAIT_VARIABLE_TEMPLATES 0
#endif
#if defined(__clang__)
#define META_IS_SAME(...) __is_same(__VA_ARGS__)
#elif defined(__GNUC__) && __GNUC__ >= 6
#define META_IS_SAME(...) __is_same_as(__VA_ARGS__)
#elif META_CXX_TRAIT_VARIABLE_TEMPLATES
#define META_IS_SAME(...) std::is_same_v<__VA_ARGS__>
#else
#define META_IS_SAME(...) std::is_same<__VA_ARGS__>::value
#endif
/// \cond
// Non-portable forward declarations of standard containers
#ifdef _LIBCPP_VERSION
#define META_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
#define META_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
#elif defined(_MSVC_STL_VERSION)
#define META_BEGIN_NAMESPACE_STD _STD_BEGIN
#define META_END_NAMESPACE_STD _STD_END
#else
#define META_BEGIN_NAMESPACE_STD namespace std {
#define META_END_NAMESPACE_STD }
#endif
#if defined(__GLIBCXX__)
#define META_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_VERSION
#define META_END_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION
#define META_BEGIN_NAMESPACE_CONTAINER _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#define META_END_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_CONTAINER
#else
#define META_BEGIN_NAMESPACE_VERSION
#define META_END_NAMESPACE_VERSION
#define META_BEGIN_NAMESPACE_CONTAINER
#define META_END_NAMESPACE_CONTAINER
#endif
#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 4000
#define META_TEMPLATE_VIS _LIBCPP_TEMPLATE_VIS
#elif defined(_LIBCPP_VERSION)
#define META_TEMPLATE_VIS _LIBCPP_TYPE_VIS_ONLY
#else
#define META_TEMPLATE_VIS
#endif
/// \endcond
namespace meta
{
#if META_CXX_INTEGER_SEQUENCE
using std::integer_sequence;
#else
template <typename T, T...>
struct integer_sequence;
#endif
template <typename... Ts>
struct list;
template <typename T>
struct id;
template <template <typename...> class>
struct quote;
template <typename T, template <T...> class F>
struct quote_i;
template <template <typename...> class C, typename... Ts>
struct defer;
template <typename T, template <T...> class C, T... Is>
struct defer_i;
#if META_CXX_VARIABLE_TEMPLATES || defined(META_DOXYGEN_INVOKED)
/// is_v
/// Test whether a type \p T is an instantiation of class
/// template \p C.
/// \ingroup trait
template <typename, template <typename...> class>
META_INLINE_VAR constexpr bool is_v = false;
template <typename... Ts, template <typename...> class C>
META_INLINE_VAR constexpr bool is_v<C<Ts...>, C> = true;
#endif
#ifdef META_CONCEPT
namespace detail
{
template <bool B>
META_INLINE_VAR constexpr bool bool_ = B;
template <class T, T> struct require_constant; // not defined
}
template <typename...>
META_CONCEPT True = META_CONCEPT_BARRIER(true);
template <typename T, typename U>
META_CONCEPT Same =
META_CONCEPT_BARRIER(META_IS_SAME(T, U));
template <template <typename...> class C, typename... Ts>
META_CONCEPT Valid = requires
{
typename C<Ts...>;
};
template <typename T, template <T...> class C, T... Is>
META_CONCEPT Valid_I = requires
{
typename C<Is...>;
};
template <typename T>
META_CONCEPT Trait = requires
{
typename T::type;
};
template <typename T>
META_CONCEPT Invocable = requires
{
typename quote<T::template invoke>;
};
template <typename T>
META_CONCEPT List = is_v<T, list>;
// clang-format off
template <typename T>
META_CONCEPT Integral = requires
{
typename T::type;
typename T::value_type;
typename T::type::value_type;
}
&& Same<typename T::value_type, typename T::type::value_type>
#if META_CXX_TRAIT_VARIABLE_TEMPLATES
&& std::is_integral_v<typename T::value_type>
#else
&& std::is_integral<typename T::value_type>::value
#endif
&& requires
{
// { T::value } -> Same<const typename T::value_type&>;
T::value;
requires Same<decltype(T::value), const typename T::value_type>;
typename detail::require_constant<decltype(T::value), T::value>;
// { T::type::value } -> Same<const typename T::value_type&>;
T::type::value;
requires Same<decltype(T::type::value), const typename T::value_type>;
typename detail::require_constant<decltype(T::type::value), T::type::value>;
requires T::value == T::type::value;
// { T{}() } -> Same<typename T::value_type>;
T{}();
requires Same<decltype(T{}()), typename T::value_type>;
typename detail::require_constant<decltype(T{}()), T{}()>;
requires T{}() == T::value;
{ T{} } -> typename T::value_type;
};
// clang-format on
#endif // META_CONCEPT
namespace extension
{
template <META_TYPE_CONSTRAINT(Invocable) F, typename L>
struct apply;
}
} // namespace meta
#ifdef __clang__
#pragma GCC diagnostic pop
#endif
#endif
/// \file
// Range v3 library
//
// Copyright Gonzalo Brito Gadeschi 2017.
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
module concepts {
umbrella "concepts"
export *
}
module meta {
umbrella "meta"
export *
}
module range_v3 {
umbrella "range"
export *
exclude header "range/v3/algorithm/tagspec.hpp"
exclude header "range/v3/at.hpp"
exclude header "range/v3/back.hpp"
exclude header "range/v3/begin_end.hpp"
exclude header "range/v3/data.hpp"
exclude header "range/v3/distance.hpp"
exclude header "range/v3/empty.hpp"
exclude header "range/v3/front.hpp"
exclude header "range/v3/getlines.hpp"
exclude header "range/v3/index.hpp"
exclude header "range/v3/istream_range.hpp"
exclude header "range/v3/iterator_range.hpp"
exclude header "range/v3/range_access.hpp"
exclude header "range/v3/range_concepts.hpp"
exclude header "range/v3/range_traits.hpp"
exclude header "range/v3/size.hpp"
exclude header "range/v3/span.hpp"
exclude header "range/v3/to_container.hpp"
exclude header "range/v3/utility/associated_types.hpp"
exclude header "range/v3/utility/basic_iterator.hpp"
exclude header "range/v3/utility/common_iterator.hpp"
exclude header "range/v3/utility/concepts.hpp"
exclude header "range/v3/utility/counted_iterator.hpp"
exclude header "range/v3/utility/dangling.hpp"
exclude header "range/v3/utility/functional.hpp"
exclude header "range/v3/utility/infinity.hpp"
exclude header "range/v3/utility/invoke.hpp"
exclude header "range/v3/utility/iterator_concepts.hpp"
exclude header "range/v3/utility/iterator_traits.hpp"
exclude header "range/v3/utility/iterator.hpp"
exclude header "range/v3/utility/nullptr_v.hpp"
exclude header "range/v3/utility/unreachable.hpp"
exclude header "range/v3/view_adaptor.hpp"
exclude header "range/v3/view_facade.hpp"
exclude header "range/v3/view_interface.hpp"
exclude header "range/v3/view/bounded.hpp"
}
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_HPP
#define RANGES_V3_ACTION_HPP
#include <range/v3/action/action.hpp>
#include <range/v3/action/adjacent_remove_if.hpp>
#include <range/v3/action/concepts.hpp>
#include <range/v3/action/drop.hpp>
#include <range/v3/action/drop_while.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/action/insert.hpp>
#include <range/v3/action/join.hpp>
#include <range/v3/action/push_back.hpp>
#include <range/v3/action/push_front.hpp>
#include <range/v3/action/remove_if.hpp>
#include <range/v3/action/reverse.hpp>
#include <range/v3/action/shuffle.hpp>
#include <range/v3/action/slice.hpp>
#include <range/v3/action/sort.hpp>
#include <range/v3/action/split.hpp>
#include <range/v3/action/split_when.hpp>
#include <range/v3/action/stable_sort.hpp>
#include <range/v3/action/stride.hpp>
#include <range/v3/action/take.hpp>
#include <range/v3/action/take_while.hpp>
#include <range/v3/action/transform.hpp>
#include <range/v3/action/unique.hpp>
#include <range/v3/action/unstable_remove_if.hpp>
#endif
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_CONTAINER_ACTION_HPP
#define RANGES_V3_CONTAINER_ACTION_HPP
#include <type_traits>
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/concepts.hpp>
#include <range/v3/functional/arithmetic.hpp>
#include <range/v3/functional/concepts.hpp>
#include <range/v3/functional/invoke.hpp>
#include <range/v3/range/concepts.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/view/ref.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace action
{
struct action_access
{
template<typename Action>
struct impl
{
// clang-format off
template<typename... Ts, typename A = Action>
static constexpr auto CPP_auto_fun(bind)(Ts &&... ts)
(
return A::bind(static_cast<Ts &&>(ts)...)
)
// clang-format on
};
};
struct make_action_fn
{
template<typename Fun>
constexpr action<Fun> operator()(Fun fun) const
{
return action<Fun>{detail::move(fun)};
}
};
/// \ingroup group-actions
/// \relates make_action_fn
RANGES_INLINE_VARIABLE(make_action_fn, make_action)
template<typename Action>
struct action : pipeable<action<Action>>
{
private:
Action action_;
friend pipeable_access;
// Piping requires things are passed by value.
template<typename Rng, typename Act>
static auto pipe(Rng && rng, Act && act)
-> CPP_ret(invoke_result_t<Action &, Rng>)( //
requires Range<Rng> && Invocable<Action &, Rng> &&
(!std::is_reference<Rng>::value))
{
return invoke(act.action_, detail::move(rng));
}
public:
action() = default;
constexpr explicit action(Action a) noexcept(
std::is_nothrow_move_constructible<Action>::value)
: action_(detail::move(a))
{}
// Calling directly requires things are passed by reference.
template<typename Rng, typename... Rest>
auto operator()(Rng & rng, Rest &&... rest) const
-> CPP_ret(invoke_result_t<Action const &, Rng &, Rest...>)( //
requires Range<Rng> && Invocable<Action const &, Rng &, Rest...>)
{
return invoke(action_, rng, static_cast<Rest &&>(rest)...);
}
// Currying overload.
// clang-format off
template<typename T, typename... Rest, typename A = Action>
auto CPP_auto_fun(operator())(T &&t, Rest &&... rest)(const)
(
return make_action(
action_access::impl<A>::bind(action_,
static_cast<T &&>(t),
static_cast<Rest &&>(rest)...))
)
// clang-format on
};
template<typename Rng, typename Action>
auto operator|=(Rng & rng, Action && action) -> CPP_ret(Rng &)( //
requires is_pipeable<Action>::value && Range<Rng &> &&
Invocable<bitwise_or, ref_view<Rng>, Action &> && Same<
ref_view<Rng>, invoke_result_t<bitwise_or, ref_view<Rng>, Action &>>)
{
view::ref(rng) | action;
return rng;
}
} // namespace action
/// @}
} // namespace ranges
#endif
/// \file
// Range v3 library
//
// Copyright Eric Niebler
// Copyright Christopher Di Bella
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_ADJACENT_REMOVE_IF_HPP
#define RANGES_V3_ACTION_ADJACENT_REMOVE_IF_HPP
#include <utility>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/algorithm/adjacent_remove_if.hpp>
#include <range/v3/functional/bind.hpp>
#include <range/v3/functional/identity.hpp>
#include <range/v3/range/traits.hpp>
#include <range/v3/utility/static_const.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace action
{
struct adjacent_remove_if_fn
{
private:
friend action_access;
template<typename Pred, typename Proj = identity>
static auto CPP_fun(bind)(adjacent_remove_if_fn adjacent_remove_if, Pred pred,
Proj proj = {})( //
requires(!Range<Pred>))
{
return std::bind(adjacent_remove_if,
std::placeholders::_1,
protect(std::move(pred)),
protect(std::move(proj)));
}
public:
template<typename Rng, typename Pred, typename Proj = identity>
auto operator()(Rng && rng, Pred pred, Proj proj = {}) const
-> CPP_ret(Rng)( //
requires ForwardRange<Rng> &&
ErasableRange<Rng, iterator_t<Rng>, sentinel_t<Rng>> &&
IndirectRelation<Pred, projected<iterator_t<Rng>, Proj>> &&
Permutable<iterator_t<Rng>>)
{
auto i = adjacent_remove_if(rng, std::move(pred), std::move(proj));
erase(rng, std::move(i), end(rng));
return static_cast<Rng &&>(rng);
}
};
/// \ingroup group-actions
/// \sa action
/// \sa with_braced_init_args
RANGES_INLINE_VARIABLE(action<adjacent_remove_if_fn>, adjacent_remove_if)
} // namespace action
/// @}
} // namespace ranges
#endif // RANGES_V3_ACTION_ADJACENT_REMOVE_IF_HPP
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_CONCEPTS_HPP
#define RANGES_V3_ACTION_CONCEPTS_HPP
#include <utility>
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/range/concepts.hpp>
#include <range/v3/range/traits.hpp>
namespace ranges
{
/// \cond
namespace detail
{
template<typename T>
struct movable_input_iterator
{
using iterator_category = std::input_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = T *;
using reference = T &&;
movable_input_iterator() = default;
movable_input_iterator & operator++();
movable_input_iterator operator++(int);
bool operator==(movable_input_iterator const &) const;
bool operator!=(movable_input_iterator const &) const;
T && operator*() const;
};
} // namespace detail
/// \endcond
/// \addtogroup group-range
/// @{
// std::array is a SemiContainer, native arrays are not.
// clang-format off
CPP_def
(
template(typename T)
concept SemiContainer,
ForwardRange<T> && DefaultConstructible<uncvref_t<T>> &&
Movable<uncvref_t<T>> &&
!View<T>
);
// std::vector is a Container, std::array is not
CPP_def
(
template(typename T)
concept Container,
SemiContainer<T> &&
Constructible<
uncvref_t<T>,
detail::movable_input_iterator<range_value_t<T>>,
detail::movable_input_iterator<range_value_t<T>>>
);
CPP_def
(
template(typename C)
concept Reservable,
requires (C &c, C const &cc, range_size_t<C> s)
(
c.reserve(s),
cc.capacity(),
cc.max_size(),
concepts::requires_<Same<decltype(cc.capacity()), range_size_t<C>>>,
concepts::requires_<Same<decltype(cc.max_size()), range_size_t<C>>>
) &&
Container<C> && SizedRange<C>
);
CPP_def
(
template(typename C, typename I)
concept ReserveAndAssignable,
requires (C &c, I i)
(
c.assign(i, i)
) &&
Reservable<C> && InputIterator<I>
);
CPP_def
(
template(typename C)
concept RandomAccessReservable,
Reservable<C> && RandomAccessRange<C>
);
// clang-format on
/// \cond
namespace detail
{
template<typename T>
auto is_lvalue_container_like(T &) noexcept -> CPP_ret(std::true_type)( //
requires Container<T>)
{
return {};
}
template<typename T>
auto is_lvalue_container_like(reference_wrapper<T>) noexcept
-> CPP_ret(meta::not_<std::is_rvalue_reference<T>>)( //
requires Container<T>)
{
return {};
}
template<typename T>
auto is_lvalue_container_like(std::reference_wrapper<T>) noexcept
-> CPP_ret(std::true_type)( //
requires Container<T>)
{
return {};
}
template<typename T>
auto is_lvalue_container_like(ref_view<T>) noexcept -> CPP_ret(std::true_type)( //
requires Container<T>)
{
return {};
}
} // namespace detail
/// \endcond
// clang-format off
CPP_def
(
template(typename T)
concept LvalueContainerLike,
requires (T &&t)
(
concepts::implicitly_convertible_to<std::true_type>(
detail::is_lvalue_container_like((T &&) t))
) &&
ForwardRange<T>
);
// clang-format on
/// @}
} // namespace ranges
#endif
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_DROP_HPP
#define RANGES_V3_ACTION_DROP_HPP
#include <functional>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/operations.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace action
{
struct drop_fn
{
private:
friend action_access;
template<typename Int>
static auto CPP_fun(bind)(drop_fn drop, Int n)( //
requires Integral<Int>)
{
return std::bind(drop, std::placeholders::_1, n);
}
public:
template<typename Rng>
auto operator()(Rng && rng, range_difference_t<Rng> n) const
-> CPP_ret(Rng)( //
requires ForwardRange<Rng> &&
ErasableRange<Rng &, iterator_t<Rng>, iterator_t<Rng>>)
{
RANGES_EXPECT(n >= 0);
ranges::action::erase(
rng, begin(rng), ranges::next(begin(rng), n, end(rng)));
return static_cast<Rng &&>(rng);
}
};
/// \ingroup group-actions
/// \relates drop_fn
/// \sa action
RANGES_INLINE_VARIABLE(action<drop_fn>, drop)
} // namespace action
/// @}
} // namespace ranges
#endif
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_DROP_WHILE_HPP
#define RANGES_V3_ACTION_DROP_WHILE_HPP
#include <functional>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/algorithm/find_if_not.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace action
{
struct drop_while_fn
{
private:
friend action_access;
template<typename Fun>
static auto CPP_fun(bind)(drop_while_fn drop_while, Fun fun)( //
requires(!Range<Fun>))
{
return std::bind(drop_while, std::placeholders::_1, std::move(fun));
}
public:
template<typename Rng, typename Fun>
auto operator()(Rng && rng, Fun fun) const -> CPP_ret(Rng)( //
requires ForwardRange<Rng> &&
IndirectUnaryPredicate<Fun, iterator_t<Rng>> &&
ErasableRange<Rng &, iterator_t<Rng>, iterator_t<Rng>>)
{
ranges::action::erase(
rng, begin(rng), find_if_not(begin(rng), end(rng), std::move(fun)));
return static_cast<Rng &&>(rng);
}
};
/// \ingroup group-actions
/// \relates drop_while_fn
/// \sa action
RANGES_INLINE_VARIABLE(action<drop_while_fn>, drop_while)
} // namespace action
/// @}
} // namespace ranges
#endif
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_ERASE_HPP
#define RANGES_V3_ACTION_ERASE_HPP
#include <utility>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/insert.hpp>
#include <range/v3/utility/static_const.hpp>
namespace ranges
{
/// \cond
namespace adl_erase_detail
{
template<typename Cont, typename I, typename S>
auto erase(Cont && cont, I begin, S end) //
-> CPP_ret(decltype(unwrap_reference(cont).erase(begin, end)))( //
requires LvalueContainerLike<Cont> && ForwardIterator<I> &&
Sentinel<S, I>)
{
return unwrap_reference(cont).erase(begin, end);
}
struct erase_fn
{
template<typename Rng, typename I, typename S>
auto operator()(Rng && rng, I begin, S end) const
-> CPP_ret(decltype(erase((Rng &&) rng, begin, end)))( //
requires Range<Rng> && ForwardIterator<I> && Sentinel<S, I>)
{
return erase(static_cast<Rng &&>(rng), begin, end);
}
};
} // namespace adl_erase_detail
/// \endcond
/// \ingroup group-actions
RANGES_INLINE_VARIABLE(adl_erase_detail::erase_fn, erase)
namespace action
{
using ranges::erase;
}
/// \addtogroup group-range
/// @{
// clang-format off
CPP_def
(
template(typename Rng, typename I, typename S)
concept ErasableRange,
requires (Rng &&rng, I begin, S end)
(
ranges::erase(static_cast<Rng &&>(rng), begin, end)
) &&
Range<Rng>
);
// clang-format on
/// @}
} // namespace ranges
#endif
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_JOIN_HPP
#define RANGES_V3_ACTION_JOIN_HPP
#include <functional>
#include <vector>
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/concepts.hpp>
#include <range/v3/action/push_back.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace action
{
template<typename Rng>
using join_action_value_t_ =
meta::if_c<(bool)ranges::Container<range_value_t<Rng>>, range_value_t<Rng>,
std::vector<range_value_t<range_value_t<Rng>>>>;
struct join_fn
{
public:
template<typename Rng>
auto operator()(Rng && rng) const -> CPP_ret(join_action_value_t_<Rng>)( //
requires InputRange<Rng> && InputRange<range_value_t<Rng>> &&
Semiregular<join_action_value_t_<Rng>>)
{
join_action_value_t_<Rng> ret;
auto end = ranges::end(rng);
for(auto it = begin(rng); it != end; ++it)
push_back(ret, *it);
return ret;
}
};
/// \ingroup group-actions
/// \relates join_fn
/// \sa action
RANGES_INLINE_VARIABLE(action<join_fn>, join)
} // namespace action
/// @}
} // namespace ranges
#endif
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_PUSH_BACK_HPP
#define RANGES_V3_ACTION_PUSH_BACK_HPP
#include <utility>
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/insert.hpp>
#include <range/v3/detail/with_braced_init_args.hpp>
#include <range/v3/utility/static_const.hpp>
namespace ranges
{
/// \cond
namespace adl_push_back_detail
{
template<typename Cont, typename T>
using push_back_t = decltype(static_cast<void>(
unwrap_reference(std::declval<Cont &>()).push_back(std::declval<T>())));
template<typename Cont, typename Rng>
using insert_t = decltype(static_cast<void>(
ranges::insert(std::declval<Cont &>(), std::declval<sentinel_t<Cont>>(),
std::declval<Rng>())));
template<typename Cont, typename T>
auto push_back(Cont && cont, T && t) -> CPP_ret(push_back_t<Cont, T>)( //
requires LvalueContainerLike<Cont> &&
(!Range<T>)&&Constructible<range_value_t<Cont>, T>)
{
unwrap_reference(cont).push_back(static_cast<T &&>(t));
}
template<typename Cont, typename Rng>
auto push_back(Cont && cont, Rng && rng) -> CPP_ret(insert_t<Cont, Rng>)( //
requires LvalueContainerLike<Cont> && Range<Rng>)
{
ranges::insert(cont, end(cont), static_cast<Rng &&>(rng));
}
// clang-format off
CPP_def
(
template(typename Rng, typename T)
concept PushBackActionConcept,
requires (Rng &&rng, T &&t)
(
push_back(rng, (T &&) t)
) &&
InputRange<Rng> &&
(Range<T> || Constructible<range_value_t<Rng>, T>)
);
// clang-format on
struct push_back_fn
{
private:
friend action::action_access;
template<typename T>
static auto bind(push_back_fn push_back, T && val)
{
return std::bind(push_back, std::placeholders::_1, bind_forward<T>(val));
}
public:
template<typename Rng, typename T>
auto operator()(Rng && rng, T && t) const -> CPP_ret(Rng)( //
requires PushBackActionConcept<Rng, T>)
{
push_back(rng, static_cast<T &&>(t));
return static_cast<Rng &&>(rng);
}
};
} // namespace adl_push_back_detail
/// \endcond
namespace action
{
/// \ingroup group-actions
RANGES_INLINE_VARIABLE(
detail::with_braced_init_args<action<adl_push_back_detail::push_back_fn>>,
push_back)
} // namespace action
using action::push_back;
} // namespace ranges
#endif
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_PUSH_FRONT_HPP
#define RANGES_V3_ACTION_PUSH_FRONT_HPP
#include <utility>
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/insert.hpp>
#include <range/v3/detail/with_braced_init_args.hpp>
#include <range/v3/utility/static_const.hpp>
namespace ranges
{
/// \cond
namespace adl_push_front_detail
{
template<typename Cont, typename T>
using push_front_t = decltype(static_cast<void>(
unwrap_reference(std::declval<Cont &>()).push_front(std::declval<T>())));
template<typename Cont, typename Rng>
using insert_t = decltype(static_cast<void>(
ranges::insert(std::declval<Cont &>(), std::declval<iterator_t<Cont>>(),
std::declval<Rng>())));
template<typename Cont, typename T>
auto push_front(Cont && cont, T && t) -> CPP_ret(push_front_t<Cont, T>)( //
requires LvalueContainerLike<Cont> &&
(!Range<T>)&&Constructible<range_value_t<Cont>, T>)
{
unwrap_reference(cont).push_front(static_cast<T &&>(t));
}
template<typename Cont, typename Rng>
auto push_front(Cont && cont, Rng && rng) -> CPP_ret(insert_t<Cont, Rng>)( //
requires LvalueContainerLike<Cont> && Range<Rng>)
{
ranges::insert(cont, begin(cont), static_cast<Rng &&>(rng));
}
// clang-format off
CPP_def
(
template(typename Rng, typename T)
concept PushFrontActionConcept,
requires (Rng &&rng, T &&t)
(
push_front(rng, (T &&) t)
) &&
InputRange<Rng> &&
(Range<T> || Constructible<range_value_t<Rng>, T>)
);
// clang-format on
struct push_front_fn
{
private:
friend action::action_access;
template<typename T>
static auto bind(push_front_fn push_front, T && val)
{
return std::bind(push_front, std::placeholders::_1, bind_forward<T>(val));
}
public:
template<typename Rng, typename T>
auto operator()(Rng && rng, T && t) const -> CPP_ret(Rng)( //
requires PushFrontActionConcept<Rng, T>)
{
push_front(rng, static_cast<T &&>(t));
return static_cast<Rng &&>(rng);
}
};
} // namespace adl_push_front_detail
/// \endcond
namespace action
{
/// \ingroup group-actions
RANGES_INLINE_VARIABLE(
detail::with_braced_init_args<action<adl_push_front_detail::push_front_fn>>,
push_front)
} // namespace action
using action::push_front;
} // namespace ranges
#endif
/// \file
// Range v3 library
//
// Copyright Andrey Diduh 2019
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_REMOVE_HPP
#define RANGES_V3_ACTION_REMOVE_HPP
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/algorithm/remove.hpp>
#include <range/v3/range/concepts.hpp>
#include <range/v3/range/traits.hpp>
#include <range/v3/utility/static_const.hpp>
namespace ranges
{
/// |cond
namespace detail
{
// clang-format off
CPP_def
(
template(typename Val, typename Rng)
concept ComparableWithRangeRef_,
EqualityComparableWith<range_reference_t<Rng>, Val>
);
// clang-format on
} // namespace detail
/// |endcond
/// \addtogroup group-actions
/// @{
namespace action
{
struct remove_fn
{
private:
friend action_access;
template<typename V, typename P>
static auto CPP_fun(bind)(remove_fn remove, V && value, P proj)( //
requires(!(Range<V> && detail::ComparableWithRangeRef_<P, V>)))
{
return std::bind(remove,
std::placeholders::_1,
bind_forward<V>(value),
protect(std::move(proj)));
}
template<typename V>
static auto bind(remove_fn remove, V && value)
{
return std::bind(
remove, std::placeholders::_1, bind_forward<V>(value), identity{});
}
public:
template<typename Rng, typename V, typename P = identity>
auto operator()(Rng && rng, V const & value, P proj = {}) const
-> CPP_ret(Rng)( //
requires ForwardRange<Rng> && Permutable<iterator_t<Rng>> &&
ErasableRange<Rng, iterator_t<Rng>, sentinel_t<Rng>> &&
IndirectRelation<equal_to, projected<iterator_t<Rng>, P>,
V const *>)
{
auto it = ranges::remove(rng, value, std::move(proj));
ranges::erase(rng, it, ranges::end(rng));
return static_cast<Rng &&>(rng);
}
};
/// \ingroup group-actions
/// \sa action
/// \sa with_braced_init_args
RANGES_INLINE_VARIABLE(action<remove_fn>, remove)
} // namespace action
/// @}
} // namespace ranges
#endif // include guard
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_REMOVE_IF_HPP
#define RANGES_V3_ACTION_REMOVE_IF_HPP
#include <utility>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/algorithm/remove_if.hpp>
#include <range/v3/functional/identity.hpp>
#include <range/v3/range/traits.hpp>
#include <range/v3/utility/static_const.hpp>
namespace ranges
{
// TODO Look at all the special cases handled by erase_if in Library Fundamentals 2
/// \addtogroup group-actions
/// @{
namespace action
{
struct remove_if_fn
{
private:
friend action_access;
template<typename C, typename P = identity>
static auto CPP_fun(bind)(remove_if_fn remove_if, C pred, P proj = P{})( //
requires(!Range<C>))
{
return std::bind(remove_if,
std::placeholders::_1,
protect(std::move(pred)),
protect(std::move(proj)));
}
public:
template<typename Rng, typename C, typename P = identity>
auto operator()(Rng && rng, C pred, P proj = P{}) const -> CPP_ret(Rng)( //
requires ForwardRange<Rng> &&
ErasableRange<Rng &, iterator_t<Rng>, iterator_t<Rng>> &&
Permutable<iterator_t<Rng>> &&
IndirectUnaryPredicate<C, projected<iterator_t<Rng>, P>>)
{
auto it = ranges::remove_if(rng, std::move(pred), std::move(proj));
ranges::erase(rng, it, ranges::end(rng));
return static_cast<Rng &&>(rng);
}
};
/// \ingroup group-actions
/// \sa action
RANGES_INLINE_VARIABLE(action<remove_if_fn>, remove_if)
} // namespace action
/// @}
} // namespace ranges
#endif
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
// Copyright Gonzalo Brito Gadeschi 2017
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_REVERSE_HPP
#define RANGES_V3_ACTION_REVERSE_HPP
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/algorithm/reverse.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/range/traits.hpp>
#include <range/v3/utility/static_const.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace action
{
/// Reversed the source range in-place.
struct reverse_fn
{
private:
friend action_access;
public:
template<typename Rng>
auto operator()(Rng && rng) const -> CPP_ret(Rng)( //
requires BidirectionalRange<Rng> && Permutable<iterator_t<Rng>>)
{
ranges::reverse(rng);
return static_cast<Rng &&>(rng);
}
};
/// \ingroup group-actions
/// \relates reverse_fn
/// \sa action
RANGES_INLINE_VARIABLE(action<reverse_fn>, reverse)
} // namespace action
/// @}
} // namespace ranges
#endif
/// \file
// Range v3 library
//
// Copyright Filip Matzner 2015
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_SHUFFLE_HPP
#define RANGES_V3_ACTION_SHUFFLE_HPP
#include <functional>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/algorithm/shuffle.hpp>
#include <range/v3/functional/invoke.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace action
{
struct shuffle_fn
{
private:
friend action_access;
template<typename Gen>
static auto CPP_fun(bind)(shuffle_fn shuffle, Gen && gen)( //
requires UniformRandomNumberGenerator<Gen>)
{
return std::bind(shuffle, std::placeholders::_1, bind_forward<Gen>(gen));
}
public:
template<typename Rng, typename Gen>
auto operator()(Rng && rng, Gen && gen) const -> CPP_ret(Rng)( //
requires RandomAccessRange<Rng> && Permutable<iterator_t<Rng>> &&
UniformRandomNumberGenerator<Gen> &&
ConvertibleTo<invoke_result_t<Gen &>, range_difference_t<Rng>>)
{
ranges::shuffle(rng, static_cast<Gen &&>(gen));
return static_cast<Rng &&>(rng);
}
};
/// \ingroup group-actions
/// \relates shuffle_fn
/// \sa `action`
RANGES_INLINE_VARIABLE(action<shuffle_fn>, shuffle)
} // namespace action
/// @}
} // namespace ranges
#endif
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_SLICE_HPP
#define RANGES_V3_ACTION_SLICE_HPP
#include <functional>
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/operations.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/view/interface.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace action
{
struct slice_fn
{
private:
friend action_access;
template<typename D>
using diff_t = range_difference_t<D>;
// Overloads for the pipe syntax: rng | action::slice(from, to)
template<typename D>
static auto CPP_fun(bind)(slice_fn slice, D from, D to)( //
requires Integral<D>)
{
return std::bind(slice, std::placeholders::_1, from, to);
}
template<typename D>
static auto CPP_fun(bind)(slice_fn slice, D from, detail::from_end_<D> to)( //
requires Integral<D>)
{
return std::bind(slice, std::placeholders::_1, from, to);
}
template<typename D>
static auto CPP_fun(bind)(slice_fn slice, detail::from_end_<D> from,
detail::from_end_<D> to)( //
requires Integral<D>)
{
return std::bind(slice, std::placeholders::_1, from, to);
}
template<typename D>
static auto CPP_fun(bind)(slice_fn slice, D from, end_fn const & to)( //
requires Integral<D>)
{
return std::bind(slice, std::placeholders::_1, from, to);
}
template<typename D>
static auto CPP_fun(bind)(slice_fn slice, detail::from_end_<D> from,
end_fn const & to)( //
requires Integral<D>)
{
return std::bind(slice, std::placeholders::_1, from, to);
}
public:
template<typename Rng, typename I = iterator_t<Rng>>
auto operator()(Rng && rng, diff_t<Rng> from, diff_t<Rng> to) const
-> CPP_ret(Rng)( //
requires ForwardRange<Rng> && ErasableRange<Rng &, I, I>)
{
RANGES_EXPECT(0 <= from && 0 <= to && from <= to);
RANGES_EXPECT(!SizedRange<Rng> || to <= distance(rng));
ranges::action::erase(rng, begin(rng), next(begin(rng), from));
ranges::action::erase(rng, next(begin(rng), to - from), end(rng));
return static_cast<Rng &&>(rng);
}
template<typename Rng, typename I = iterator_t<Rng>>
auto operator()(Rng && rng, diff_t<Rng> from,
detail::from_end_<diff_t<Rng>> to) const -> CPP_ret(Rng)( //
requires BidirectionalRange<Rng> && ErasableRange<Rng &, I, I>)
{
RANGES_EXPECT(0 <= from && to.dist_ <= 0);
RANGES_EXPECT(!SizedRange<Rng> || from - to.dist_ <= distance(rng));
ranges::action::erase(rng, begin(rng), next(begin(rng), from));
if(to.dist_ != 0)
{
auto const last = next(begin(rng), end(rng));
ranges::action::erase(rng, prev(last, -to.dist_), last);
}
return static_cast<Rng &&>(rng);
}
template<typename Rng, typename I = iterator_t<Rng>>
auto operator()(Rng && rng, detail::from_end_<diff_t<Rng>> from,
detail::from_end_<diff_t<Rng>> to) const -> CPP_ret(Rng)( //
requires BidirectionalRange<Rng> && ErasableRange<Rng &, I, I>)
{
RANGES_EXPECT(from.dist_ <= 0 && to.dist_ <= 0 && from.dist_ <= to.dist_);
RANGES_EXPECT(!SizedRange<Rng> || 0 <= distance(rng) + from.dist_);
auto last = next(begin(rng), end(rng));
ranges::action::erase(rng, prev(last, -to.dist_), last);
last = next(begin(rng), end(rng));
ranges::action::erase(rng, begin(rng), prev(last, to.dist_ - from.dist_));
return static_cast<Rng &&>(rng);
}
template<typename Rng, typename I = iterator_t<Rng>>
auto operator()(Rng && rng, diff_t<Rng> from, end_fn const &) const
-> CPP_ret(Rng)( //
requires ForwardRange<Rng> && ErasableRange<Rng &, I, I>)
{
RANGES_EXPECT(0 <= from);
RANGES_EXPECT(!SizedRange<Rng> || from <= distance(rng));
ranges::action::erase(rng, begin(rng), next(begin(rng), from));
return static_cast<Rng &&>(rng);
}
template<typename Rng, typename I = iterator_t<Rng>>
auto operator()(Rng && rng, detail::from_end_<diff_t<Rng>> from,
end_fn const &) const -> CPP_ret(Rng)( //
requires BidirectionalRange<Rng> && ErasableRange<Rng &, I, I>)
{
RANGES_EXPECT(from.dist_ <= 0);
RANGES_EXPECT(!SizedRange<Rng> || 0 <= distance(rng) + from.dist_);
auto const last = next(begin(rng), end(rng));
ranges::action::erase(rng, begin(rng), prev(last, -from.dist_));
return static_cast<Rng &&>(rng);
}
};
/// \ingroup group-actions
/// \relates slice_fn
/// \sa action
RANGES_INLINE_VARIABLE(action<slice_fn>, slice)
} // namespace action
/// @}
} // namespace ranges
#endif
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment