Compare commits

...

10 commits

Author SHA1 Message Date
6c079839c2 Release: version of upcoming release -- with Git-flow
Starting with ''preview release'' `v0.pre.04`, branch and version tags
will be handled in accordance to the **Git-flow** naming scheme.
Notably this implies that from now on the version in-tree will indicate
the ''next expected release,'' adorned by a suffix to mark the preview.

To accommodate this transition to Git-flow
- the new branch `integration` will be introduced
- the version number will once (and the last time for this release)
  be adjusted ''before'' forking the release branch
- branch `master` will transition to reflect the latest released state
- several existing branches will be discontinued, notably
  `gui`, `steam`, `vault`, `release`, `play`
2025-07-21 03:23:45 +02:00
17ee3ac1cb Release: Introduce the Git-flow branching model
Starting with the upcoming ''preview release'', branches, branch names and tags
will be rearranged to follow the Git-flow pattern instead of the existing
ad-hoc organisation with a release branch.

The documentation provided here defines the actual naming conventions
and some fine points regarding the version number upgrades
and placement of release tags.


Furthermore, two helper-scripts are provided to automate version number updates
- `buildVersion.py` : extract current version from git tag and allow to bump version
- `setVersion` : manipulate all relevant files with `sed` to update the version info
2025-07-21 02:46:28 +02:00
20f3252892 Upgrade: down with typename!!
Yet another chainsaw massacre.

One of the most obnoxious annoyances with C++ metaprogramming
is the need to insert `typename` and `template` qualifiers into
most definitions, to help the compiler to cope with the syntax,
which is not context-free.

The recent standards adds several clarifications, so that most
of these qualifiers are redundant now, at least at places where
it is unambiguously clear that only a type can be given.

GCC already supports most of these relaxing rules
(Clang unfortunately lags way behind with support of newer language features...)
2025-07-06 01:19:08 +02:00
2cd3e95228 Upgrade: simplify Either-type
`lib::Result` can invoke, capture the result and thereby
represent ''either'' a result or a failure.

The old implementation required a delegate, due to the complexities
of integrating the `void` case. With C++23, `invoke_r` from the Stdlib
handles those issues, allowing a cleaner formulation, with directly
capturing the result into `lib::ItemWrapper`
2025-07-04 21:27:50 +02:00
b6a39fa831 Upgrade: simplify comparisons
Now able to remove most complicated comparison operators and most usages of boost::operators...
In most cases it is sufficient just to define one ''spaceship operator'',
and often even that one can be synthesised.

However — we still use boost::operators for arithmetic types,
notably the `lib::time::TimeValue`, which is addable and mutipliable
2025-07-04 03:37:54 +02:00
bad4827b34 Upgrade: Literal can be constexpr
Only minor rearrangements necessary to make that possible with C++20
And while at this change (which requires a full rebuild of Lumiera)

- simplify the defined comparison operators, as C++20 can infer most variations
- also mark various usages of `const char*` either as Literal or CStr

Remark: regarding copyright, up to now this is entirely my work,
        with two major creation steps in 2008 (conception) and
        in 2017 (introduction of a symbol table)
2025-07-02 22:18:39 +02:00
170b68ac5c Upgrade: further extend usage of the tuple_like concept + generic apply
This changeset removes various heuristics and marker-traits
by a constraint to tuple_like types. Furthermore, several usages
of `apply` can thereby be generalised to work on any tuple_like.

This generalisation is essential for the passing generic data blocks
via `FeedManifold` into the node invocation
2025-07-02 01:16:08 +02:00
3a5bbd8fb4 Upgrade: put the new tuple_like concept into use
- integrate the concept definition into tuple-helper.hpp
- use it to replace the `is_Structured` traits check
- do not need `enable_if_TupleProtocol` any more

Integrate test coverage of the concept metafunctions
and the generalised get accessor

''This changeset was made at LAC 2025 in Lyon, France''
2025-06-28 00:42:23 +02:00
3a1f64ec41 Upgrade: now able to reformulate the tuple_like concept
Now this draft seems ready to be put into actual use in the code base.
Furthermore, a generic ''get adapter'' is introduced to level the difference
between both tolerated forms of element access, also working correctly
for const and RValue references
2025-06-24 01:03:57 +02:00
bb0b73e2a7 Upgrade: switch existing usages of forEachIDX
...to rely on the new formulation and the extended template `WithIdxSeq`

This is in preparation to use this new iteration scheme also from the tuple_like concept
2025-06-23 22:59:37 +02:00
187 changed files with 3500 additions and 1809 deletions

2
README
View file

@ -1,6 +1,6 @@
Lumiera -- the video NLE for Linux
====================================
Version: 0.pre.03
Version: 0.pre.04~rc.1
:Date: 11/2015
*************************************************************

145
admin/buildVersion.py Executable file
View file

@ -0,0 +1,145 @@
#!/usr/bin/python3
# coding: utf-8
##
## buildVersion.py - extract and possibly bump current version from Git
##
# Copyright (C)
# 2025, Hermann Vosseler <Ichthyostega@web.de>
#
# **Lumiera** is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version. See the file COPYING for further details.
#####################################################################
'''
Build and possibly bump a current project version spec,
based on the nearest Git tag.
'''
import re
import os
import sys
import datetime
import argparse
import subprocess
#------------CONFIGURATION----------------------------
CMDNAME = os.path.basename(__file__)
TAG_PAT = 'v*.*'
VER_SEP = r'(?:^v?|\.)'
VER_NUM = r'(\w[\w\+]*)'
VER_SUB = r'(?:'+VER_SEP+VER_NUM+')'
VER_SUF = r'(?:~('+VER_NUM+VER_SUB+'?'+'))'
VER_SYNTAX = VER_SUB +VER_SUB+'?' +VER_SUB+'?' +VER_SUF+'?'
GIT = 'git'
#------------CONFIGURATION----------------------------
def parseAndBuild():
''' main: parse cmdline and generate version string '''
parser = argparse.ArgumentParser (prog=CMDNAME, description='%s: %s' % (CMDNAME, __doc__)
,formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument ('--bump','-b'
,nargs='?'
,choices=['maj','min','rev'], const='rev'
,help='bump the version detected from Git (optionally bump a specific component)')
parser.add_argument ('--suffix','-s'
,help='append (or replace) a suffix (by default attached with ~)')
parser.add_argument ('--snapshot'
,action='store_true'
,help='mark as development snapshot by appending ~dev.YYYYMMDDhhmm, using UTC date from HEAD commit')
opts = parser.parse_args()
version = getVersionFromGit()
version = rebuild (version, **vars(opts))
print (version)
def getVersionFromGit():
get_nearest_matching_tag = 'describe --tags --abbrev=0 --match=' + TAG_PAT
return runGit (get_nearest_matching_tag)
def getTimestampFromGit():
get_head_author_date = 'show -s --format=%ai'
timespec = runGit (get_head_author_date)
timespec = datetime.datetime.fromisoformat (timespec)
timespec = timespec.astimezone (datetime.timezone.utc) # note: convert into UTC
return timespec.strftime ('%Y%m%d%H%M')
def rebuild (version, bump=None, suffix=None, snapshot=False):
mat = re.fullmatch (VER_SYNTAX, version)
if not mat:
__FAIL ('invalid version syntax in "'+version+'"')
maj = mat.group(1)
min = mat.group(2)
rev = mat.group(3)
suf = mat.group(4)
suf_idi = mat.group(5) # detail structure not used (as of 2025)
suf_num = mat.group(6)
if bump=='maj':
maj = bumpedNum(maj)
min = None
rev = None
elif bump=='min':
min = bumpedNum(min)
rev = None
elif bump=='rev':
rev = bumpedNum(rev)
if snapshot:
suf = 'dev.'+getTimestampFromGit()
elif suffix:
suf = suffix
version = maj
if min:
version += '.'+min
elif not min and rev:
version += '.0'
if rev:
version += '.'+rev
if suf:
version += '~'+suf
return version
def bumpedNum (verStr):
mat = re.match (r'\d+', str(verStr))
if not mat:
return '1'
numStr = mat.group(0)
num = int(numStr) + 1
return str(num).zfill(len(numStr))
def runGit (argStr):
''' run Git as system command without shell and retrieve the output '''
argList = [GIT] + argStr.split()
try:
proc = subprocess.run (argList, check=True, capture_output=True, encoding='utf-8', env={'LC_ALL':'C'})
return proc.stdout.rstrip() # Note: sanitised env
except:
__FAIL ('invoking git-describe')
def __ERR (*args, **kwargs):
print (*args, file=sys.stderr, **kwargs)
def __FAIL (msg):
__ERR ("FAILURE: "+msg)
exit (-1)
if __name__=='__main__':
parseAndBuild()

View file

@ -22,7 +22,7 @@ import Options
#-------------------------------------------------------Configuration
TARGDIR = 'target'
VERSION = '0.pre.03'
VERSION = '0.pre.04~rc.1'
TOOLDIR = './admin/scons' # SCons plugins
OPTCACHE = 'optcache'
CUSTOPTFILE = 'custom-options'

44
admin/setVersion Executable file
View file

@ -0,0 +1,44 @@
#!/bin/bash
#
# setVersion - place the version info given as argument
# into all the necessary places in the Lumiera tree
#
#
set -e
function fail() {
echo -e "\nFAIL: $1\n\n"
exit -1
}
PROJ_ROOT=$(git rev-parse --show-toplevel)
cd $PROJ_ROOT
[ $# -eq 1 ] || fail "need version as argument\n\nsetVersion <ver>"
[ -n "$1" ] || fail "need a nonemty version spec"
VER="$1"
function rewrite() {
# Process the indicated file with sed and replace the existing version spec
# The PREFIX argument must match everything from line start before the version;
# then the _remainder_ of this line will be replaced by the NEWVER
FILE="$1"
PREFIX="$2"
NEWVER="$3"
echo "rewrite..... $FILE"
egrep -q "^$PREFIX" $FILE || fail "not found in $FILE : $PREFIX"
#
sed -r -f - -i "$FILE" <<END_SCRIPT
/^$PREFIX/ {
s/(^$PREFIX).+/\1 $NEWVER/
}
END_SCRIPT
}
rewrite data/config/setup.ini 'version\s*=' "$VER"
rewrite doc/devel/Doxyfile 'PROJECT_NUMBER\s*=' "$VER"
rewrite doc/devel/Doxyfile.browse 'PROJECT_NUMBER\s*=' "$VER"
rewrite admin/scons/Setup.py 'VERSION\s*=' "\'$VER\'"
rewrite README 'Version:' "$VER"
echo -e "\nSUCCESSFULLY rewritten version $VER\ncheck git diff\n\n"

View file

@ -12,7 +12,7 @@ gui = gtk_gui.lum
modulepath = $ORIGIN/modules
configpath = $ORIGIN/../../share/lumiera/config:$ORIGIN/config:~/.lumiera # currently unused (2/2011)
title = Lumiera
version = 0.pre.03
version = 0.pre.04~rc.1
website = http://www.lumiera.org
authors = Joel Holdsworth|Christian Thäter|Hermann Voßeler|Stefan Kangas|Michael Fisher|Michael Ploujnikov|and others...
copyright = 2007 - 2025

View file

@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = Lumiera
PROJECT_NUMBER = 0.pre.03
PROJECT_NUMBER = 0.pre.04~rc.1
PROJECT_BRIEF = "»edit your freedom«"
PROJECT_LOGO = draw/rendered/LumiLogo-small.png
OUTPUT_DIRECTORY =

View file

@ -14,7 +14,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = Lumiera
PROJECT_NUMBER = 0.pre.03
PROJECT_NUMBER = 0.pre.04~rc.1
PROJECT_LOGO = draw/rendered/LumiLogo-small.png
OUTPUT_DIRECTORY =
CREATE_SUBDIRS = NO

View file

@ -0,0 +1,213 @@
Git-flow branching pattern
==========================
:Date: Summer 2025
:toc:
:toclevels: 3
_Lumiera uses Git-flow for branching and release organisation_
.Motivation
Lumiera is a large project with an elaborate structure.
Development and integration efforts, refactorings, releases and bugfixes require some degree
of coordination -- to avoid confusion, collisions and wasted effort. Git is a flexible tool
and can be adapted to a wide array of organisation styles; by means of a time-proven pattern
for branches, merges, names and tags, it is possible to represent the activities related to
releases and bugfixes directly as structure in the Git history, without much need for explicit
release planning, coordination and management.
TIP: The principles and procedures of *Git-flow* are explained in this
->{nbsp}{l}/project/background/GitFlow.html[Background Article]. First
link:https://nvie.com/posts/a-successful-git-branching-model/[published in 2010]
by _Vincent Driessen_, meanwhile it is widely applied in projects with regular releases
and external liabilities -- and often seen as the counterpoint to trunk centred
development and continuous delivery.
The Framework
-------------
The actual entity maintained in Git repositories is _a history line,_ leading to a _Head._
Developers collaborate by pulling the history from _some other repository,_ extending or
remoulding this history by adding some changes as _commits_ and finally they publish this
extended line into their _personal repository._ However, the _normative state_ of the project
is represented by the link:https://git.lumiera.org/gitweb?p=LUMIERA[»Lumiera Repository«]
`git://git.lumiera.org/LUMIERA`
The Core Developer(s) can _push_ to this repository, thereby acting as _Gateway._ Automated builds
will listen to this repository, and any further _downstream processes,_ like e.g. packaging,
are always based on this state. What is described in the following sections however is a
_pattern of naming and branch organisation_ -- and can be seen as orthogonal to the former:
A structure of branches and tags is assembled, gradually, in some repository; yet whenever the
Core Developer(s) push this state to the Lumiera Repository, this structure becomes the
normative state of the project. A release happens when the release tag is published this way.
Development and Production
~~~~~~~~~~~~~~~~~~~~~~~~~~
The development is the source of _change._ It builds the application, creates new functionality,
maintains and evolves the structure of the code. On the other side, the productive use of the
application requires _stability._ Users must be confident that they can rely on Lumiera for
reaching deadlines and to build their long-term work. These two poles are represented by the
two permanent branches: The *development mainline* and the *production master*.
A release process brings change into a stable shape; it is represented by a *release branch*,
which originates from development, goes through a vetting process and finally _ends_ with
a *release tag* on production master. Urgent *bugfixes* are based on current production
master, and released immediately back to production with a *patch tag*.
Every delivery to production is also *back-merged* into the development mainline one way
or another.footnote:[Some fine points to consider here. These back-merges will typically
result in merge conflicts, which require manual handling. This is a desired feature,
because reconciling the release changes with ongoing development is essential integration
work and also supports the knowledge transfer between developers; it is recommended to
consult both parties involved to find a long-term solution when resolution becomes
complicated. Note however that the version bumping both on development and for the
actual release will cause a spurious conflict, which must always be resolved in favour
of the version present on the development line. This task can be automated. And finally,
when a bugfix happens _while a release is in-flight,_ then the back-merge
*must be done to the release branch*, not the development branch -- because we need the
bugfix to be present in the next release too. Failure to observe this special rule will
cause a *regression*, i.e. loosing the fix with the next regular release.]
This is a distinguishing feature of Git-flow and addresses the quite common problem
that bugfix work can be lost for the ongoing development.
Naming Convention
~~~~~~~~~~~~~~~~~
master::
the branch name used for the infinite line of production code
integration::
the branch name used for the infinite ongoing main line of development
v<ver>::
naming pattern for version tags; `<ver>` is the version number string
(maybe{nbsp}transliterated to make it valid for Git. Notably `'~'` -> `'_'`)
rel/<ver>::
naming pattern for release branches; `<ver>` is the version number string
for the upcoming release. Only a single release branch is allowed at any
given time, and will be deleted after the release merge and tag is set.
fix/<ver>::
naming pattern for bugfix branches; here `<ver>` is the patch version
string, usually with an incremented revision component (maj.min.rev).
Only a single bugfix branch is allowed at any given time; these
branches are also deleted after publishing the fix.
dev/<id>::
naming pattern for a development or feature branch; `<id>` is an mnemonic
identifier, which must be unique at the time while the branch exists.
Development branches are transient and must be deleted after _landing_.footnote:[
Sometimes a development effort does not succeed -- or is abandoned for various
reasons; if this happens, mark the last state with a tag and _delete_ the branch.
A well maintained repository should not contain stale branches.]
dev/stage dev/steam dev/vault::
these development branch names _can_ be used for pre-integration of development
within a layer, in a situation where there is a dedicated sub-team and some
elaborated yet isolated development is going on.footnote:[As of 2025, this
situation is hypothetical; in the early stages of the Lumiera project, we
had three developers working in a relatively independent and often quite
experimental way, with several further minor contributors. In such a situation,
a staged integration can be helpful. Unless the project becomes _very large_
eventually, it seems much more likely that long-lived feature branches will
be used for changes cross-cutting all layers.]
documentation::
a special branch which is immediately published to the Lumiera website;
the ASCIIDOC sources of user, design and technical docs are kept in-tree
and often augmented simultaneously on several branches -- for that reason
the currently published documentation might diverge at times, and will
typically be re-joined with the development mainline during the convergence
phase before a release. This branch can be fast-forwarded and merged,
but never be re-wound or rebased.
deb::
a special _downstream branch_ which carries the debian packaging, as
maintained by the Lumiera team and published through the Lumiera DEB depot.
This branch is not visible in the Lumiera project repository, but rather
published via a special link:https://git.lumiera.org/gitweb?p=debian/lumiera[DEB repository].
<email>/<branch>_signature::
GPG signed tags from the Core Developer(s); these tags are frequently force-reset
to a new position, and indicate that this branch position was reviewed and
approved.footnote:[The relevance of such an ongoing reveiw and trust marker
is based in a preference for an open and chaotic approach to development.
People may try out things, and collaborate directly. We even maintain a
link:https://git.lumiera.org/gitweb?p=lumiera/mob[»Mob repository«]
that is _world-pushable_ for small ad-hoc contributions. This option was used
indeed, and we never had problems with vandalism. Admittedly, since several
years now the ongoing development is way too demanding and esoteric to
encourage such low-barrier access, but the vision as such is maintained,
hoping to reach a state of the project eventually where direct small-scale
contributions will be feasible again (e.g. for plug-ins, configuration,
tweaks, styling)]
Version numbers
^^^^^^^^^^^^^^^
The link:{rfc}/VersionNumberScheme.html[Version Number scheme of Lumiera]
is based on the Debian
link:https://www.debian.org/doc/debian-policy/ch-controlfields.html#version[policy for version numbers];
note that this policy definition even provides a nice algorithm for version number sorting.
In a nutshell, we alternatingly compare non-numeric and numeric parts of version number strings.
And `'~'` sorts _before_ anything else, even the empty string, `'+'` sorts before `'.'` and
`'-'` (dash) is not allowed, because it is reserved for Debian revisions.
Notably we have the convention to mark development snapshots with a version number
_preceding_ the next expected release, and we do the same with release candiates (`'rc'`);
in all those cases, we attach a suffix with a tilde, because this orders _before_ the
decorated number: `1.4~dev` comes before `1.4~rc.1` and again before `1.4`
However, the way we use version tags, a tilde will never show up either on a
release branch, nor in the tag itself. These fine distinctions will only be used
in the version definition checked into the source tree and picked up by the build
system and thus also by the continuous integration.footnote:[as of 2025, we do not
have (and do not need yet) a continuous integration; so the actual modus operandi
still needs to be figured out.]
Procedures
----------
Release process
~~~~~~~~~~~~~~~
What follows is a short summary of the stages and procedures for a release.
1. Prior to the release, there is a convergence phase
- attempt to land features which should be part of the release
- stabilise the code and resolve bugs
- keep breaking changes on feature branches
2. Cut the release, once the code is feature complete
- possibly adjust the expected version number based on the current situation
- fork the release branch off `integration`, using the expected version number
- bump the version number on the `integration` branch, and attach a `~dev` suffix.footnote:[
Note there are some scripts in the 'admin' subdirectory to help with version number handling.]
3. Get the release code to maturity
- additional testing, possibly a public beta
- directly fix any bugs encountered on the release branch
- avoid any breaking changes and refrain from adding further features
- release candidates can be used simply by committing them into the version in-tree;
indicate the RC in the commit message, but do not tag them
- with the last commit, add the release notes and remove the `~rc` suffix
4. Publish the release
- merge the release branch into `master` (this will never create a conflict)
- set the release tag on this merge commit
- publish this state of the history to the Lumiera project repository
5. Complete the relase cycle
- create a back-merge from the release tag to the `integration` branch
- ensure that the integration branch has still the correct verion number, which
should be the next one, with a `~dev` suffix.footnote:[...to achieve this, just
re-run the script in a similar way as was used to bump the version after forking
the release branch.]
- resolve any conflicts due to integration of release changes with ongoing development
- delete the release branch.
Bugfixes between Releases
^^^^^^^^^^^^^^^^^^^^^^^^^
1. initiate bugfix
- create a bugfix branch from current `master`; include the bugfix number
- the first commit on the bugfix branch sets this bugfix number in-tree,
thereby typically adding or increasing the revision component of the version
2. landing the bugfix
- once the problem is resolved and tested, merge back bugfix branch into `master`
- merge the bugfix into `integration`
- delete the bugfix branch
Bugfix during Release prep
^^^^^^^^^^^^^^^^^^^^^^^^^^
1. initiate bugfix
- create a bugfix branch from current `master`; include the bugfix number
- use a version _prior_ to the ongoing release, but increment the revision component
- commit this bugfix number in-tree
2. landing the bugfix
- after resolving the problem, merge directly to `master`
- be sure to merge the bugfix then *into the release branch*
- delete the bugfix branch

View file

@ -2,6 +2,9 @@ Code Base Organisation
======================
//Menu: label Code Base
//Menu: prepend child CodingGuidelines
//Menu: put child LinkingStructure after CodingGuidelines
//Menu: put child GitBranching after LinkingStructure
This section of Lumiera's technical documentation deals with the code base as such,

View file

@ -184,8 +184,44 @@ pick and manipulate individually::
can be programmed recursively, similar to LISP. The »bridge« is to unpack the variadic argument pack
into the `lib::meta::Types<ARGS...>`
+
meta-manipulations::
When you need to rebind and manipulate a variadic sequence, it helps to transform the sequence
into one of our meta sequence representations (`lib::meta::Types` or the Loki typelists).
In `variadic-helper.hpp`, we define a convenient rebinding template `lib::meta::Elms<>`,
which can work transparently on any type sequence or any tuple-like entity
+
- to get at the variadics in a sequence representation
- to get a matching index sequence
- to rebind into another variadic template, using the same variadic sequence
- to apply a meta-function on each of the variadic types
- to compute a conjunction or disjunction of meta-predicates over the sequence
+
tuple-like::
This is a concept to match on any type in compliance with the »tuple protocol«
+
- such a type must inject a specialisation of `std::tuple_size<TY>`
- and it must likewise support `std::tuple_element_t<N, TY>`
- and, based on that, expose a constexpr _getter function_
- together this also implies, that such a type can be used in _structured bindings_
(but note, structured bindings also work on plain arrays and on simple structs,
which are _not_ considered _tuple-like_ by themselves)
+
apply to tuple-likes::
Unfortunately, the standard has a glaring deficiency here, insofar it defines an _exposition only_
concept, which is then hard mapped to support only some fixed types from the STL (tuples, pairs,
std::array and some range stuff). This was one of the main reasons to define our own `concept tuple_like`
+
- but unfortunately, `std::apply` was fixed with C++20 to allow only the above mentioned fixed set of
types from the STL, while in theory there is no reason why not to allow any _tuple-like_ entity
- this forces us to define our own `lib::meta::apply` as a drop-in replacement for `std::apply`
- in addition to that, we also define a `lib::meta::getElm<N, TY>`, which is an universal getter
to work on any _tuple-like_, either with a `get` member function or a free-ADL function `get`
- note that starting with C++20 it is forbidden to inject function overloads into namespace std,
and thus a free `get` function must be injected as friend via ADL and used appropriately, i.e.
unqualified.
+
apply functor to each tuple element::
A common trick is to use `std::apply` in combination with a _fold-expression_
A common trick is to use `apply` in combination with a _fold-expression_
+
- provided as `lib::meta::forEach` in 'lib/meta/tuple-helper.hpp
- The design of the `DataTable` with CSV-Formatting is based on this technique, see 'lib/stat/data.hpp'

View file

@ -12,6 +12,8 @@
/** @file try.cpp
* Develop a concept to detect _tuple-like_ classes, based on the requirements
* of the »tuple protocol«. Using some ideas from [Stackoverflow] as starting point.
* However, we model both a _friend function_ `get` and a similar member function
* as alternatives for element access, and we break down the checks into sub-concepts.
* [Stackoverflow]: https://stackoverflow.com/q/68443804/444796
*/
@ -27,58 +29,6 @@
using std::string;
namespace lib {
namespace meta {
template<class TUP>
concept tuple_sized = requires
{
{ std::tuple_size<TUP>::value } -> std::convertible_to<size_t>;
};
template<class TUP, std::size_t N>
concept tuple_adl_accessible = requires(TUP tup)
{
typename std::tuple_element_t<N, TUP>;
{ get<N>(tup) } -> std::convertible_to<std::tuple_element_t<N, TUP>&>;
};
template<class TUP, std::size_t N>
concept tuple_mem_accessible = requires(TUP tup)
{
typename std::tuple_element_t<N, TUP>;
{ tup.template get<N>() } -> std::convertible_to<std::tuple_element_t<N, TUP>&>;
};
template<class TUP, std::size_t N>
concept tuple_accessible = tuple_mem_accessible<TUP,N> or tuple_adl_accessible<TUP,N>;
template<class TUP>
class AndAll
{
template<size_t...idx>
static constexpr bool
canAccessAll (std::index_sequence<idx...>)
{
return (tuple_accessible<TUP, idx> and ...);
}
using IdxSeq = typename ElmTypes<TUP>::Idx;
public:
static constexpr bool can_AccessElement = canAccessAll(IdxSeq{});
};
template<class TUP>
concept tuple_like = not is_reference_v<TUP>
and tuple_sized<remove_cv_t<TUP>>
and AndAll<remove_cv_t<TUP>>::can_AccessElement;
}}//namespace lib::meta
template<typename X>
void
@ -103,7 +53,7 @@ show()
int
main (int, char**)
{
using Tup = std::tuple<long>;
using Tup = std::tuple<long,short>;
using Arr = std::array<int,3>;
using Hetero = lib::HeteroData<int,string>::Chain<short>::ChainExtent<bool,lib::meta::Nil>::ChainType;
@ -112,11 +62,11 @@ main (int, char**)
SHOW_EXPR((lib::meta::tuple_sized<Hetero> ))
SHOW_EXPR((lib::meta::tuple_sized<int> ))
SHOW_EXPR((lib::meta::tuple_accessible<Tup,0>))
// SHOW_EXPR((lib::meta::tuple_accessible<Tup,2>))
SHOW_EXPR((lib::meta::tuple_accessible<Hetero,0>))
SHOW_EXPR((lib::meta::AndAll<Tup>::can_AccessElement))
SHOW_EXPR((lib::meta::AndAll<Hetero>::can_AccessElement))
SHOW_EXPR((lib::meta::tuple_element_accessible<Tup,0>))
// SHOW_EXPR((lib::meta::tuple_element_accessible<Tup,2>))
SHOW_EXPR((lib::meta::tuple_element_accessible<Hetero,0>))
SHOW_EXPR((lib::meta::tuple_accessible<Tup>))
SHOW_EXPR((lib::meta::tuple_accessible<Hetero>))
SHOW_EXPR((lib::meta::tuple_like<Tup> ))
SHOW_EXPR((lib::meta::tuple_like<Arr> ))
@ -128,9 +78,25 @@ main (int, char**)
show<Hetero>();
show<int>();
SHOW_EXPR(bool(std::is_integral_v<int>))
SHOW_EXPR(bool(std::is_integral_v<char>))
SHOW_EXPR(bool(std::is_integral_v<double>))
SHOW_EXPR((std::tuple_size_v<const Tup>))
using Elm1 = std::tuple_element_t<1, const Tup>;
SHOW_TYPE(Elm1)
using TupConstSeq = lib::meta::ElmTypes<const Tup>::Seq;
SHOW_TYPE(TupConstSeq)
using T1 = decltype(lib::meta::getElm<0> (std::declval<Tup>()));
SHOW_TYPE(T1)
using T2 = decltype(lib::meta::getElm<0> (std::declval<Tup&>()));
SHOW_TYPE(T2)
using T3 = decltype(lib::meta::getElm<0> (std::declval<Tup const&>()));
SHOW_TYPE(T3)
using H1 = decltype(lib::meta::getElm<4> (std::declval<Hetero>()));
SHOW_TYPE(H1)
using H2 = decltype(lib::meta::getElm<4> (std::declval<Hetero&>()));
SHOW_TYPE(H2)
using H3 = decltype(lib::meta::getElm<4> (std::declval<Hetero const&>()));
SHOW_TYPE(H3)
cout << "\n.gulp." <<endl;
return 0;

View file

@ -21,7 +21,7 @@
**
** This header is intended to be incorporated as part of the advice system implementation (advice.cpp).
** It is \em not usable as an external interface. But it is written in a rather self-contained manner,
** in order to be testable in isolation. To this end, the actual PointOfAdvice entities being organised
** in order to be testable in isolation. To this end, the actual PointOfAdvice entities \a POA organised
** by this index datastructure remain abstract (defined as template parameter), and are only manipulated
** through the following functions:
** - \c hash_value(POA)
@ -87,7 +87,6 @@
#include "lib/util.hpp"
#include "common/advice/binding.hpp"
#include <boost/operators.hpp>
#include <unordered_map>
#include <string>
@ -122,6 +121,7 @@ namespace advice {
* by invoking the \c setSolution() function on the
* corresponding PointOfAdvice entity.
*
* @tparam POA _point-of-advice_ exposing a matcher and solution
* @note element \em identity is defined in terms of pointing
* to the same memory location of a POA (point of advice).
* Thus e.g. #hasProvision means this index holds an entry
@ -141,12 +141,8 @@ namespace advice {
class Index
{
struct Entry
: pair<Binding::Matcher, POA*>
, boost::equality_comparable<Entry, POA,
boost::equality_comparable<Entry>
>
{
explicit
Entry (POA& elm)
@ -175,8 +171,8 @@ namespace advice {
};
typedef vector<Entry> EntryList;
typedef typename EntryList::iterator EIter;
using EntryList = vector<Entry>;
using EIter = EntryList::iterator;
struct Cluster
@ -253,7 +249,7 @@ namespace advice {
POA*
find_latest_solution (POA& requestElm)
{
typedef typename EntryList::reverse_iterator RIter;
using RIter = EntryList::reverse_iterator;
Binding::Matcher pattern (requestElm.getMatcher());
for (RIter ii=this->elms_.rbegin();
ii!=this->elms_.rend();
@ -518,8 +514,8 @@ namespace advice {
bool
Index<POA>::isValid() const
{
typedef typename RTable::const_iterator RTIter;
typedef typename PTable::const_iterator PTIter;
using RTIter = RTable::const_iterator;
using PTIter = PTable::const_iterator;
try {
for (PTIter ii =provisionEntries_.begin();

View file

@ -112,7 +112,7 @@ namespace lumiera {
/** The ServiceHandle automatically creates and manages the Proxy instance */
template<class I, class FA>
using ServiceHandle = typename lib::DependInject<FA>::template ServiceInstance<Proxy<InstanceHandle<I,FA>>>;
using ServiceHandle = lib::DependInject<FA>::template ServiceInstance<Proxy<InstanceHandle<I,FA>>>;
/**

View file

@ -76,9 +76,9 @@
#include "lib/util.hpp"
#include <boost/lexical_cast.hpp>
#include <boost/operators.hpp>
#include <memory>
#include <typeinfo>
#include <compare>
#include <memory>
#include <cctype>
#include <string>
@ -136,6 +136,8 @@ namespace lumiera {
: kind(k)
, type(t)
{ }
auto operator<=> (QueryID const&) const =default;
};
QueryID const&
@ -185,26 +187,6 @@ namespace lumiera {
};
inline bool
operator< (Goal::QueryID const& id1, Goal::QueryID const& id2)
{
return id1.kind < id2.kind
or(id1.kind == id2.kind and id1.type < id2.type);
}
inline bool
operator== (Goal::QueryID const& id1, Goal::QueryID const& id2)
{
return id1.kind == id2.kind
and id1.type == id2.type;
}
inline bool
operator!= (Goal::QueryID const& id1, Goal::QueryID const& id2)
{
return not (id1 == id2);
}
namespace {
@ -386,7 +368,6 @@ namespace lumiera {
* Implicitly convertible to and from Query instances.
*/
class QueryKey
: boost::totally_ordered<QueryKey>
{
Goal::QueryID id_;
lib::QueryText def_;
@ -442,21 +423,19 @@ namespace lumiera {
}
friend bool
operator< (QueryKey const& q1, QueryKey const& q2)
friend std::strong_ordering
operator<=> (QueryKey const& q1, QueryKey const& q2)
{
uint d1 = q1.degree();
uint d2 = q2.degree();
return d1 < d2
or(d1 == d2 and ( q1.def_ < q2.def_
or (q1.def_ == q2.def_ and q1.id_ < q2.id_)));
}
friend bool
operator== (QueryKey const& q1, QueryKey const& q2)
{
return q1.def_ == q2.def_;
if (auto o1 = d1 <=> d2; o1 != 0)
return o1;
if (auto o2 = q1.def_ <=> q2.def_; o2 != 0)
return o2;
else
return q1.id_ <=> q2.id_;
}
bool operator== (QueryKey const&) const =default;
friend size_t
hash_value (QueryKey const& q)
@ -559,7 +538,7 @@ namespace lumiera {
template<class RES>
inline typename Query<RES>::Builder
inline Query<RES>::Builder
Query<RES>::build (Kind queryType)
{
return Builder(defineQueryTypeID (queryType));
@ -567,7 +546,7 @@ namespace lumiera {
template<class RES>
inline typename Query<RES>::Builder
inline Query<RES>::Builder
Query<RES>::rebuild() const
{
return Builder(this->id_, getQueryDefinition());

View file

@ -78,7 +78,7 @@ namespace query {
/** we maintain an independent defaults registry
* for every participating kind of object. */
typedef std::vector< P<TableEntry> > Table;
using Table = std::vector< P<TableEntry> >;
/**
@ -132,7 +132,7 @@ namespace query {
struct Slot
: public TableEntry
{
typedef std::set<Record<TAR>> Registry;
using Registry = std::set<Record<TAR>>;
Registry registry;
static size_t index; ///< where to find this Slot in every Table
@ -194,7 +194,7 @@ namespace query {
class Iter
{
friend class DefsRegistry;
typedef typename Slot<TAR>::Registry::iterator II;
using II = Slot<TAR>::Registry::iterator;
II p,i,e;
P<TAR> next, ptr;
@ -251,12 +251,12 @@ namespace query {
{
P<TAR> dummy;
Record<TAR> entry (query, dummy);
typedef typename Slot<TAR>::Registry Registry;
using Registry = Slot<TAR>::Registry;
Registry& registry = Slot<TAR>::access(table_);
// try to get a possible direct match (same query)
typename Registry::iterator pos = registry.find (entry);
typename Registry::iterator end = registry.end();
auto pos = registry.find (entry);
auto end = registry.end();
if (pos==end)
return Iter<TAR> (registry.begin(), end); // just enumerate contents
@ -277,8 +277,8 @@ namespace query {
put (P<TAR> const& obj, Query<TAR> const& query)
{
Record<TAR> entry (query, obj);
typedef typename Slot<TAR>::Registry Registry;
typedef typename Registry::iterator RIter;
using Registry = Slot<TAR>::Registry;
using RIter = Registry::iterator;
Registry& registry = Slot<TAR>::access(table_);
RIter pos = registry.lower_bound (entry);
@ -306,8 +306,8 @@ namespace query {
bool
forget (P<TAR> const& obj)
{
typedef typename Slot<TAR>::Registry Registry;
typedef typename Record<TAR>::Search SearchFunc;
using Registry = Slot<TAR>::Registry;
using SearchFunc = Record<TAR>::Search;
Registry& registry = Slot<TAR>::access(table_);
return util::remove_if(registry, SearchFunc (obj));

View file

@ -137,7 +137,7 @@ namespace lumiera {
template<typename RES>
inline typename Query<RES>::iterator
inline Query<RES>::iterator
Query<RES>::resolveBy (QueryResolver const& resolver) const
{
PReso resultSet = resolver.issue (*this);
@ -150,7 +150,7 @@ namespace lumiera {
/** notational convenience shortcut,
* synonymous to Query<RES>::resolveBy() */
template<typename RES>
inline typename Query<RES>::iterator
inline Query<RES>::iterator
Query<RES>::operator() (QueryResolver const& resolver) const
{
return resolveBy (resolver);

View file

@ -41,11 +41,11 @@ namespace lumiera {
using lib::Symbol;
//defined in liblumiera.so
extern const char * ON_BASIC_INIT; ///< automatic static init. treated specially to run as soon as possible
extern const char * ON_GLOBAL_INIT; ///< to be triggered in main() @note no magic!
extern const char * ON_GLOBAL_SHUTDOWN; ///< to be triggered at the end of main() @note no magic!
extern CStr ON_BASIC_INIT; ///< automatic static init. treated specially to run as soon as possible
extern CStr ON_GLOBAL_INIT; ///< to be triggered in main() @note no magic!
extern CStr ON_GLOBAL_SHUTDOWN; ///< to be triggered at the end of main() @note no magic!
extern const char * ON_EMERGENCY; ///< activated on shutdown after premature failure of a subsystem
extern CStr ON_EMERGENCY; ///< activated on shutdown after premature failure of a subsystem
// client code is free to register and use additional lifecycle events

View file

@ -347,14 +347,14 @@ namespace lib {
struct SetupSeveral<std::void_t, lib::AllocationCluster&>
{
template<typename X>
using Adapter = typename AllocationCluster::template Allocator<X>;
using Adapter = AllocationCluster::template Allocator<X>;
template<class I, class E>
struct Policy
: AllocationPolicy<I,E,Adapter>
{
using Base = AllocationPolicy<I,E,Adapter>;
using Bucket = typename Base::Bucket;
using Bucket = Base::Bucket;
/** @warning allocation size is severely limited in AllocationCluster. */
size_t static constexpr ALLOC_LIMIT = AllocationCluster::max_size();

View file

@ -89,7 +89,7 @@ namespace lib {
{
using Allo = ALO;
using AlloT = std::allocator_traits<Allo>;
using BaseType = typename Allo::value_type;
using BaseType = Allo::value_type;
Allo& baseAllocator() { return *this; }
@ -97,7 +97,7 @@ namespace lib {
auto
adaptAllocator()
{
using XAllo = typename AlloT::template rebind_alloc<X>;
using XAllo = AlloT::template rebind_alloc<X>;
if constexpr (std::is_constructible_v<XAllo, Allo>)
return XAllo{baseAllocator()};
else
@ -105,8 +105,8 @@ namespace lib {
}
template<class ALOT, typename...ARGS>
typename ALOT::pointer
construct (typename ALOT::allocator_type& allo, ARGS&& ...args)
ALOT::pointer
construct (ALOT::allocator_type& allo, ARGS&& ...args)
{
auto loc = ALOT::allocate (allo, 1);
try { ALOT::construct (allo, loc, std::forward<ARGS>(args)...); }
@ -120,7 +120,7 @@ namespace lib {
template<class ALOT>
void
destroy (typename ALOT::allocator_type& allo, typename ALOT::pointer elm)
destroy (ALOT::allocator_type& allo, ALOT::pointer elm)
{
ALOT::destroy (allo, elm);
ALOT::deallocate (allo, elm, 1);
@ -167,7 +167,7 @@ namespace lib {
}
else
{
using XAlloT = typename AlloT::template rebind_traits<TY>;
using XAlloT = AlloT::template rebind_traits<TY>;
auto xAllo = adaptAllocator<TY>();
return construct<XAlloT> (xAllo, std::forward<ARGS>(args)...);
}
@ -184,7 +184,7 @@ namespace lib {
}
else
{
using XAlloT = typename AlloT::template rebind_traits<TY>;
using XAlloT = AlloT::template rebind_traits<TY>;
auto xAllo = adaptAllocator<TY>();
destroy<XAlloT> (xAllo, elm);
}
@ -334,7 +334,7 @@ namespace lib {
{
storage_.erase (pos); // EX_FREE
const char* errID = lumiera_error();
CStr errID = lumiera_error();
ERROR (memory, "Allocation failed with unknown exception. "
"Lumiera errorID=%s", errID?errID:"??");
throw;

View file

@ -148,8 +148,8 @@ namespace lib {
class DependInject
: util::NoInstance
{
using Factory = typename Depend<SRV>::Factory;
using Lock = typename Depend<SRV>::Lock;
using Factory = Depend<SRV>::Factory;
using Lock = Depend<SRV>::Lock;
public:
/** configure dependency-injection for type SRV to build a subclass singleton.
@ -178,8 +178,8 @@ namespace lib {
static void
useSingleton (FUN&& ctor)
{
using Sub = typename SubclassFactoryType<FUN>::Subclass;
using Fun = typename SubclassFactoryType<FUN>::Functor;
using Sub = SubclassFactoryType<FUN>::Subclass;
using Fun = SubclassFactoryType<FUN>::Functor;
__assert_compatible<Sub>();
installFactory<Sub,Fun> (forward<FUN> (ctor));
@ -372,9 +372,9 @@ namespace lib {
static_assert (meta::_Fun<FUN>(),
"Need a Lambda or Function object to create a heap allocated instance");
using Functor = typename meta::_Fun<FUN>::Functor; // suitable type to store for later invocation
using ResultVal = typename meta::_Fun<FUN>::Ret;
using Subclass = typename meta::Strip<ResultVal>::TypePlain;
using Functor = meta::_Fun<FUN>::Functor; // suitable type to store for later invocation
using ResultVal = meta::_Fun<FUN>::Ret;
using Subclass = meta::Strip<ResultVal>::TypePlain;
static_assert (std::is_pointer<ResultVal>::value,
"Function must yield a pointer to a heap allocated instance");

View file

@ -106,7 +106,7 @@ namespace diff{
struct InterpreterScheme ///< base case is to expect typedef I::Val
{
using Interpreter = I;
using Val = typename I::Val;
using Val = I::Val;
using Handler = HandlerFun<I,Val>;
};
@ -188,12 +188,12 @@ namespace diff{
struct DiffStepBuilder
{
using Scheme = InterpreterScheme<I>;
using Handler = typename Scheme::Handler;
using Val = typename Scheme::Val;
using Handler = Scheme::Handler;
using Val = Scheme::Val;
using Lang = DiffLanguage<I,Val>;
using Step = typename Lang::DiffStep;
using Verb = typename Lang::DiffVerb;
using Step = Lang::DiffStep;
using Verb = Lang::DiffVerb;
Handler handler;
Literal id;
@ -239,7 +239,7 @@ namespace diff{
* @warning use for internal state marking only --
* invoking this token produces undefined behaviour */
template<class I, typename E>
const typename DiffLanguage<I,E>::DiffStep DiffLanguage<I,E>::NIL = DiffStep(DiffVerb(), E());
const DiffLanguage<I,E>::DiffStep DiffLanguage<I,E>::NIL = DiffStep(DiffVerb(), E());

View file

@ -119,7 +119,7 @@ namespace diff{
struct RecordSetup<GenNode>
{
using Storage = std::vector<GenNode>;
using ElmIter = typename Storage::const_iterator;
using ElmIter = Storage::const_iterator;
/** using const reference data access
* relevant for handling large subtrees */
@ -269,11 +269,11 @@ namespace diff{
, data(std::forward<X>(val))
{ }
GenNode(string const& symbolicID, const char* text)
GenNode(string const& symbolicID, CStr text)
: GenNode(symbolicID, string(text))
{ }
GenNode(const char* text)
GenNode(CStr text)
: GenNode(string(text))
{ }
@ -516,7 +516,7 @@ namespace diff{
using No = lib::meta::No_t;
template<class X>
static Yes check(typename variant::CanBuildFrom<X, DataValues>::Type*);
static Yes check(variant::CanBuildFrom<X, DataValues>::Type*);
template<class X>
static No check(...);

View file

@ -69,8 +69,8 @@ namespace diff{
/* === forwarded sequence access === */
using iterator = typename std::vector<VAL>::iterator;
using const_iterator = typename std::vector<VAL>::const_iterator;
using iterator = std::vector<VAL>::iterator;
using const_iterator = std::vector<VAL>::const_iterator;
iterator begin() { return data_.begin(); }
iterator end() { return data_.end(); }

View file

@ -64,7 +64,7 @@ namespace diff{
: public ListDiffInterpreter<E>
{
using Vec = vector<E,ARGS...>;
using Iter = typename Vec::iterator;
using Iter = Vec::iterator;
Vec orig_;
Vec& seq_;

View file

@ -78,14 +78,14 @@ namespace diff{
class DiffDetector
: util::NonCopyable
{
using Val = typename SEQ::value_type;
using Val = SEQ::value_type;
using Idx = IndexTable<Val>;
Idx refIdx_;
SEQ const& currentData_;
using DiffStep = typename ListDiffLanguage<Val>::DiffStep;
using DiffStep = ListDiffLanguage<Val>::DiffStep;
/** @internal state frame for diff detection and generation. */
class DiffFrame;

View file

@ -140,9 +140,9 @@ namespace diff{
template<typename VAL>
class Record
{
using Storage = typename RecordSetup<VAL>::Storage;
using ElmIter = typename RecordSetup<VAL>::ElmIter;
using Access = typename RecordSetup<VAL>::Access;
using Storage = RecordSetup<VAL>::Storage;
using ElmIter = RecordSetup<VAL>::ElmIter;
using Access = RecordSetup<VAL>::Access;
string type_;
@ -307,7 +307,7 @@ namespace diff{
/* ==== Exposing scope and contents for iteration ====== */
using iterator = IterAdapter<ElmIter, const Record*>;
using scopeIter = typename iter_stl::_SeqT<const Storage>::Range;
using scopeIter = iter_stl::_SeqT<const Storage>::Range;
using keyIter = TransformIter<scopeIter, string>;
using valIter = TransformIter<scopeIter, Access>;
@ -595,10 +595,10 @@ namespace diff{
* @see tree-diff-application.hpp
*/
template<typename VAL>
inline typename Record<VAL>::Mutator&
inline Record<VAL>::Mutator&
mutateInPlace (Record<VAL>& record_to_mutate)
{
return reinterpret_cast<typename Record<VAL>::Mutator &> (record_to_mutate);
return reinterpret_cast<Record<VAL>::Mutator &> (record_to_mutate);
}
@ -713,8 +713,8 @@ namespace diff{
struct RecordSetup<string>
{
using Storage = std::vector<string>;
using ElmIter = typename Storage::const_iterator;
using Access = string; ///< data access by value copy
using ElmIter = Storage::const_iterator;
using Access = string; ///< data access by value copy
};

View file

@ -195,8 +195,8 @@ namespace diff{
public:
using iterator = typename iter_stl::_SeqT<VecG>::Range;
using const_iterator = typename iter_stl::_SeqT<const VecG>::Range;
using iterator = iter_stl::_SeqT<VecG>::Range;
using const_iterator = iter_stl::_SeqT<const VecG>::Range;
const_iterator begin() const { return eachElm(content_); }
const_iterator end() const { return const_iterator(); }

View file

@ -364,7 +364,7 @@ namespace diff{
void
initDiffApplication()
{
using Target = typename TreeDiffTraits<TAR>::Ret;
using Target = TreeDiffTraits<TAR>::Ret;
Target target = mutatorBinding (subject_);
buildMutator(target)->init();

View file

@ -200,10 +200,10 @@ namespace diff{
* the return value in local scope as long as necessary
*/
template<class TAR>
typename TreeDiffTraits<TAR>::Ret
TreeDiffTraits<TAR>::Ret
mutatorBinding (TAR& subject)
{
using Wrapper = typename TreeDiffTraits<TAR>::Ret;
using Wrapper = TreeDiffTraits<TAR>::Ret;
return Wrapper(subject);
}

View file

@ -236,9 +236,9 @@ namespace diff{
class ChangeOperation
: public AttributeBindingBase<PAR>
{
using CloArgs = typename lib::meta::_Fun<CLO>::Args;
using ValueType = typename lib::meta::Pick<CloArgs, 0>::Type;
using ID = idi::EntryID<ValueType>;
using CloArgs = lib::meta::_Fun<CLO>::Args;
using ValueType = lib::meta::Pick<CloArgs, 0>::Type;
using ID = idi::EntryID<ValueType>;
CLO setter_;

View file

@ -121,8 +121,8 @@ namespace diff{
struct ContainerTraits<V, IF_is_vector<V> >
{
using Vec = _AsVector<V>;
using Elm = typename Vec::value_type;
using Itr = typename Vec::iterator;
using Elm = Vec::value_type;
using Itr = Vec::iterator;
static Itr
recentElmRawIter (Vec& vec)
@ -141,8 +141,8 @@ namespace diff{
struct ContainerTraits<M, IF_is_map<M> >
{
using Map = _AsMap<M>;
using Key = typename Map::key_type;
using Val = typename Map::mapped_type;
using Key = Map::key_type;
using Val = Map::mapped_type;
using Elm = std::pair<const Key, Val>;
/** heuristic for `std::map`: lookup via reverse iterator.
@ -188,12 +188,12 @@ namespace diff{
struct CollectionBinding
: util::MoveOnly
{
using Coll = typename Strip<COLL>::TypeReferred;
using Elm = typename Coll::value_type;
using Coll = Strip<COLL>::TypeReferred;
using Elm = Coll::value_type;
using Trait = ContainerTraits<Coll>;
using iterator = typename lib::iter_stl::_SeqT<Coll>::Range;
using const_iterator = typename lib::iter_stl::_SeqT<const Coll>::Range;
using iterator = lib::iter_stl::_SeqT<Coll>::Range;
using const_iterator = lib::iter_stl::_SeqT<const Coll>::Range;
ASSERT_VALID_SIGNATURE (MAT, bool(GenNode const& spec, Elm const& elm))
@ -306,7 +306,7 @@ namespace diff{
class ChildCollectionMutator
: public PAR
{
using Iter = typename BIN::iterator;
using Iter = BIN::iterator;
BIN binding_;
Iter pos_;
@ -582,7 +582,7 @@ namespace diff{
inline auto
createCollectionBindingBuilder (COLL& coll, MAT m, CTR c, SEL s, ASS a, MUT u)
{
using Coll = typename Strip<COLL>::TypeReferred;
using Coll = Strip<COLL>::TypeReferred;
return CollectionBindingBuilder<Coll, MAT,CTR,SEL,ASS,MUT> {coll, m,c,s,a,u};
}
@ -738,7 +738,7 @@ namespace diff{
inline auto
collection (COLL& coll)
{
using Elm = typename COLL::value_type;
using Elm = COLL::value_type;
return _DefaultBinding<Elm>::attachTo(coll);
}

View file

@ -82,8 +82,8 @@ namespace lib {
: public std::vector<P<ELM>>
{
using _Vec = std::vector<P<ELM>>;
using Iter = typename _Vec::iterator;
using CIter = typename _Vec::const_iterator;
using Iter = _Vec::iterator;
using CIter = _Vec::const_iterator;
public:
~ElementTracker()
@ -226,7 +226,7 @@ namespace lib {
/** storage for the functor to link an AutoRegistered entity
* to the corresponding registration service */
template<typename TAR>
typename AutoRegistered<TAR>::RegistryLink AutoRegistered<TAR>::getRegistry;
AutoRegistered<TAR>::RegistryLink AutoRegistered<TAR>::getRegistry;

View file

@ -39,19 +39,20 @@
#include <exception>
#include <string>
using CStr = const char*;
#define LERR_(_NAME_) lumiera::error::LUMIERA_ERROR_##_NAME_
namespace lumiera {
using std::string;
using CStr = const char*;
namespace error {
/** error-ID for unspecified exceptions */
LUMIERA_ERROR_DECLARE(EXCEPTION);
}
using std::string;
/**
* Interface and Base definition for all Lumiera Exceptions.
@ -266,13 +267,13 @@ namespace lumiera {
#define ERROR_LOG_AND_IGNORE(_FLAG_,_OP_DESCR_) \
catch (std::exception& problem) \
{ \
const char* errID = lumiera_error(); \
CStr errID = lumiera_error(); \
WARN (_FLAG_, "%s failed: %s", _OP_DESCR_, problem.what()); \
TRACE (debugging, "Error flag was: %s", errID);\
} \
catch (...) \
{ \
const char* errID = lumiera_error(); \
CStr errID = lumiera_error(); \
ERROR (_FLAG_, "%s failed with unknown exception; " \
"error flag is: %s" \
, _OP_DESCR_, errID?errID:"??"); \
@ -281,14 +282,14 @@ namespace lumiera {
#define ERROR_LOG_AND_RETHROW(_FLAG_,_OP_DESCR_) \
catch (std::exception& problem) \
{ \
const char* errID = lumiera_error(); \
CStr errID = lumiera_error(); \
WARN (_FLAG_, "%s failed: %s", _OP_DESCR_, problem.what()); \
TRACE (debugging, "Error flag was: %s", errID); \
throw; \
} \
catch (...) \
{ \
const char* errID = lumiera_error(); \
CStr errID = lumiera_error(); \
ERROR (_FLAG_, "%s failed with unknown exception; " \
"error flag is: %s" \
, _OP_DESCR_, errID?errID:"??"); \
@ -304,7 +305,7 @@ namespace lumiera {
#define ON_EXCEPTION_RETURN(_VAL_,_OP_DESCR_) \
catch (std::exception& problem) \
{ \
const char* errID = lumiera_error(); \
CStr errID = lumiera_error(); \
WARN (stage, "%s (Handler) failed: %s", \
_OP_DESCR_, problem.what()); \
TRACE (debugging, "Error flag was: %s", errID); \
@ -312,7 +313,7 @@ namespace lumiera {
} \
catch (...) \
{ \
const char* errID = lumiera_error(); \
CStr errID = lumiera_error(); \
ERROR (stage, "(Handler) %s failed with " \
"unknown exception; error flag is: %s" \
, _OP_DESCR_, errID?errID:"??"); \

View file

@ -190,7 +190,7 @@ namespace util {
inline std::string
toString (TY const& val) noexcept
{
using PlainVal = typename lib::meta::Strip<TY>::TypeReferred;
using PlainVal = lib::meta::Strip<TY>::TypeReferred;
return StringConv<PlainVal>::invoke (val);
}

View file

@ -76,7 +76,7 @@ namespace util {
/** in case the formatting of a (primitive) value fails,
* we try to supply an error indicator instead */
void
pushFailsafeReplacement (std::byte* formatter, const char* errorMsg =NULL)
pushFailsafeReplacement (std::byte* formatter, CStr errorMsg =nullptr)
try {
string placeholder("<Error");
if (errorMsg){

View file

@ -182,11 +182,11 @@ namespace util {
friend std::ostream&
operator<< (std::ostream& os, _Fmt const&);
friend bool operator== (_Fmt const&, _Fmt const&);
friend bool operator== (_Fmt const&, string const&);
friend bool operator== (_Fmt const&, const char * const);
friend bool operator== (string const& , _Fmt const&);
friend bool operator== (const char * const, _Fmt const&);
friend bool operator== (_Fmt const&, _Fmt const&);
friend bool operator== (_Fmt const&, string const&);
friend bool operator== (_Fmt const&, CStr const );
friend bool operator== (string const&, _Fmt const&);
friend bool operator== (CStr const, _Fmt const&);
template<typename X>
friend bool operator != (_Fmt const& fmt, X const& x) { return not (fmt == x); }
@ -299,7 +299,7 @@ namespace util {
inline void
_clear_errorflag()
{
const char* errID = lumiera_error();
CStr errID = lumiera_error();
TRACE_IF (errID, progress, "Lumiera errorstate '%s' cleared.", errID);
}
@ -318,7 +318,7 @@ namespace util {
inline string
_log_unknown_exception()
{
const char* errID = lumiera_error();
CStr errID = lumiera_error();
if (errID)
ERROR (progress, "Unknown error while invoking custom string conversion. Lumiera error flag = %s", errID);
else
@ -368,10 +368,10 @@ namespace util {
};
template<>
struct _Fmt::Converter<const char *>
struct _Fmt::Converter<CStr>
{
static void
dump (const char* cString, Implementation& impl)
dump (CStr cString, Implementation& impl)
{
format (cString? cString : BOTTOM_INDICATOR, impl);
}
@ -473,7 +473,7 @@ namespace util {
}
inline bool
operator== (_Fmt const& fmt, const char * const cString)
operator== (_Fmt const& fmt, CStr const cString)
{
return string(fmt) == string(cString);
}
@ -485,7 +485,7 @@ namespace util {
}
inline bool
operator== (const char * const cString, _Fmt const& fmt)
operator== (CStr const cString, _Fmt const& fmt)
{
return fmt == cString;
}

View file

@ -133,7 +133,7 @@ namespace util {
inline auto
stringify (IT&& src)
{
using Val = typename lib::meta::ValueTypeBinding<IT>::value_type;
using Val = lib::meta::ValueTypeBinding<IT>::value_type;
return lib::transformIterator(forward<IT>(src), util::toString<Val>);
}
@ -144,7 +144,7 @@ namespace util {
template<class CON, typename TOGGLE = void>
struct _RangeIter
{
using StlIter = typename CON::const_iterator;
using StlIter = CON::const_iterator;
lib::RangeIter<StlIter> iter;
@ -193,7 +193,7 @@ namespace util {
inline string
join (COLL&& coll, string const& delim =", ")
{
using Coll = typename lib::meta::Strip<COLL>::TypePlain;
using Coll = lib::meta::Strip<COLL>::TypePlain;
_RangeIter<Coll> range(std::forward<COLL>(coll)); // copies when CON is reference
auto strings = stringify (std::move (range.iter));

View file

@ -24,6 +24,8 @@
** @deprecated 10/2024 seems very likely that similar functionality moves down
** into the render-engine implementation and will no longer be considered
** a constituent of the public interface.
** @todo 6/2025 basically everything here is unused or will likely be done
** in a different way expect this and rendergraph.cpp to be obsolete
*/
@ -31,7 +33,8 @@
#define LUMIERA_FRAMEID_H
#include <boost/operators.hpp>
#include "lib/integral.hpp"
#include <compare>
namespace lumiera {
@ -73,15 +76,14 @@ namespace lumiera {
* later on define what is actually needed; this header should then
* be replaced by a combined C/C++ header
*/
class FrameID : boost::totally_ordered<FrameID> ////////////TODO it seems we don't need total ordering, only comparison. Clarify this!
class FrameID
{
long dummy;
public:
FrameID(long dum=0) : dummy(dum) {}
operator long () { return dummy; }
bool operator< (const FrameID& other) const { return dummy < other.dummy; }
bool operator== (const FrameID& other) const { return dummy == other.dummy; }
auto operator<=> (FrameID const&) const =default;
};

View file

@ -183,7 +183,7 @@ namespace lib {
/** access type to reside in the given slot of the _complete chain_ */
template<size_t slot>
using Elm_t = typename PickType<slot>::type;
using Elm_t = PickType<slot>::type;
/** access data elements within _complete chain_ by index pos */
@ -272,10 +272,10 @@ namespace lib {
}
template<typename...XVALS>
using ChainExtent = typename ChainType::template Chain<XVALS...>;
using ChainExtent = ChainType::template Chain<XVALS...>;
template<size_t slot>
using Accessor = typename ChainType::template Accessor<_Self::size()+slot>;
using Accessor = ChainType::template Accessor<_Self::size()+slot>;
template<typename X>
using AccessorFor = Accessor<meta::indexOfType<X,VALS...>()>;
@ -310,7 +310,7 @@ namespace lib {
using _FrontBlock = HeteroData<meta::Node<StorageFrame<0, DATA...>, meta::Nil>>;
public:
using NewFrame = typename _FrontBlock::Frame;
using NewFrame = _FrontBlock::Frame;
using ChainType = _FrontBlock;
using _FrontBlock::_FrontBlock;
@ -434,7 +434,7 @@ namespace std { // Specialisation to support C++ »Tuple Protocol« and structur
template<size_t I, typename...DATA>
struct tuple_element<I, lib::HeteroData<DATA...> >
{
using type = typename lib::HeteroData<DATA...>::template Elm_t<I>;
using type = lib::HeteroData<DATA...>::template Elm_t<I>;
};
template<size_t I>
struct tuple_element<I, lib::HeteroData<lib::meta::Nil> >

View file

@ -47,7 +47,7 @@
#include "lib/util.hpp"
#include <boost/functional/hash.hpp>
#include <boost/operators.hpp>
#include <compare>
#include <string>
@ -131,7 +131,6 @@ namespace idi {
* for building a combined hash and symbolic ID.
*/
class BareEntryID
: public boost::equality_comparable<BareEntryID>
{
string symbol_;
@ -217,7 +216,6 @@ namespace idi {
template<class TY>
struct EntryID
: BareEntryID
, boost::totally_ordered< EntryID<TY> >
{
/** case-1: auto generated symbolic ID */
@ -234,7 +232,7 @@ namespace idi {
: BareEntryID (util::sanitise(symbolID), getTypeHash<TY>())
{ }
explicit
EntryID (const char* symbolID)
EntryID (CStr symbolID)
: BareEntryID (util::sanitise(symbolID), getTypeHash<TY>())
{ }
@ -272,15 +270,17 @@ namespace idi {
explicit
operator string() const;
friend bool operator< (EntryID const& i1, EntryID const& i2) { return i1.getSym() < i2.getSym(); }
friend auto operator<=> (EntryID const& i1, EntryID const& i2) { return i1.getSym() <=> i2.getSym(); }
};
inline bool
operator== (BareEntryID const& i1, BareEntryID const& i2)
{
return i1.getHash() == i2.getHash();
}
// Note: since we allow comparison only between EntryIDs of same type
// and also feed-down the symbol into the hash value, both equality
// and (total) ordering mesh up perfectly.
@ -296,7 +296,7 @@ namespace idi {
RandID (string const& symbolID)
: BareEntryID{util::sanitise (symbolID)}
{ }
RandID (const char* symbolID)
RandID (CStr symbolID)
: BareEntryID{util::sanitise (symbolID)}
{ }
RandID (Symbol const& internalSymbol)

View file

@ -50,8 +50,8 @@ namespace lib {
using ResVal = decltype(data_->operator[](0));
using value_type = typename meta::RefTraits<ResVal>::Value;
using reference = typename meta::RefTraits<ResVal>::Reference;
using value_type = meta::RefTraits<ResVal>::Value;
using reference = meta::RefTraits<ResVal>::Reference;
bool
checkPoint() const
@ -113,7 +113,7 @@ namespace lib {
: public iter::IndexAccessCore<PTR>::IterWrapper
{
using _Cor = iter::IndexAccessCore<PTR>;
using _Par = typename _Cor::IterWrapper;
using _Par = _Cor::IterWrapper;
public:
IndexIter() = default;

View file

@ -60,10 +60,10 @@ namespace lib {
public:
/** this iterator adapter is meant to wrap an iterator yielding pointer values */
using pointer = typename meta::ValueTypeBinding<IT>::value_type;
using pointer = meta::ValueTypeBinding<IT>::value_type;
static_assert(std::is_pointer_v<pointer>);
using value_type = typename std::remove_pointer_t<pointer>;
using value_type = std::remove_pointer_t<pointer>;
using reference = value_type&;
@ -72,10 +72,10 @@ namespace lib {
// the purpose of the following typedefs is to support building a correct "const iterator"
using ValueTypeBase = typename std::remove_const_t<value_type>; // value_type without const
using ValueTypeBase = std::remove_const_t<value_type>; // value_type without const
using WrappedIterType = typename IterType<IT>::template SimilarIter< ValueTypeBase* * >::Type;
using WrappedConstIterType = typename IterType<IT>::template SimilarIter<const ValueTypeBase* * >::Type;
using WrappedIterType = IterType<IT>::template SimilarIter< ValueTypeBase* * >::Type;
using WrappedConstIterType = IterType<IT>::template SimilarIter<const ValueTypeBase* * >::Type;
using IterType = PtrDerefIter<WrappedIterType>;
using ConstIterType = PtrDerefIter<WrappedConstIterType>;
@ -220,7 +220,7 @@ namespace lib {
template<class IT>
class AddressExposingIter
{
using _Ptr = typename IT::pointer;
using _Ptr = IT::pointer;
IT i_; ///< nested source iterator
@ -238,9 +238,9 @@ namespace lib {
public:
using pointer = typename IT::pointer const*;
using reference = typename IT::pointer const&;
using value_type = typename IT::pointer const ;
using pointer = IT::pointer const*;
using reference = IT::pointer const&;
using value_type = IT::pointer const ;
ENABLE_USE_IN_STD_RANGE_FOR_LOOPS (AddressExposingIter);

View file

@ -49,9 +49,9 @@ namespace iter_stl {
class DistinctIter
{
public:
using value_type = typename IT::value_type;
using reference = typename IT::reference;
using pointer = typename IT::pointer;
using value_type = IT::value_type;
using reference = IT::reference;
using pointer = IT::pointer;
private:
IT i_;
@ -96,9 +96,9 @@ namespace iter_stl {
template<typename DEF>
struct WrappedStlIter : DEF
{
using Iter = typename DEF::Iter;
using reference = typename DEF::reference;
using pointer = typename DEF::pointer;
using Iter = DEF::Iter;
using reference = DEF::reference;
using pointer = DEF::pointer;
WrappedStlIter() : i_() { }
@ -127,9 +127,9 @@ namespace iter_stl {
struct Wrapped_Identity
{
using Iter = IT;
using value_type = typename IT::value_type;
using reference = typename IT::reference;
using pointer = typename IT::pointer;
using value_type = IT::value_type;
using reference = IT::reference;
using pointer = IT::pointer;
static Iter get (Iter& it) { return & (*it); }
};
@ -142,7 +142,7 @@ namespace iter_stl {
struct Wrapped_PickKey
{
using Iter = IT;
using value_type = typename IT::value_type::first_type;
using value_type = IT::value_type::first_type;
using reference = value_type &;
using pointer = value_type *;
@ -157,7 +157,7 @@ namespace iter_stl {
struct Wrapped_PickVal
{
using Iter = IT;
using value_type = typename IT::value_type::second_type;
using value_type = IT::value_type::second_type;
using reference = value_type &;
using pointer = value_type *;
@ -168,7 +168,7 @@ namespace iter_stl {
struct Wrapped_PickConstVal
{
using Iter = IT;
using value_type = const typename IT::value_type::second_type;
using value_type = const IT::value_type::second_type;
using reference = const value_type &;
using pointer = const value_type *;
@ -185,17 +185,17 @@ namespace iter_stl {
template<class MAP>
struct _MapTypeSelector
{
using Key = typename MAP::value_type::first_type;
using Val = typename MAP::value_type::second_type;
using Itr = typename MAP::iterator;
using Key = MAP::value_type::first_type;
using Val = MAP::value_type::second_type;
using Itr = MAP::iterator;
};
template<class MAP>
struct _MapTypeSelector<const MAP>
{
using Key = typename MAP::value_type::first_type;
using Val = typename MAP::value_type::second_type const;
using Itr = typename MAP::const_iterator;
using Key = MAP::value_type::first_type;
using Val = MAP::value_type::second_type const;
using Itr = MAP::const_iterator;
};
/** helper to access the parts of the pair values correctly...*/
@ -219,13 +219,13 @@ namespace iter_stl {
template<class MAP>
struct _MapT
{
using KeyType = typename _MapTypeSelector<MAP>::Key;
using ValType = typename _MapTypeSelector<MAP>::Val;
using EntryIter = typename _MapTypeSelector<MAP>::Itr;
using KeyType = _MapTypeSelector<MAP>::Key;
using ValType = _MapTypeSelector<MAP>::Val;
using EntryIter = _MapTypeSelector<MAP>::Itr;
using DetectConst = typename EntryIter::reference;
using PickKeyIter = typename _MapSubSelector<EntryIter,DetectConst>::PickKey;
using PickValIter = typename _MapSubSelector<EntryIter,DetectConst>::PickVal;
using DetectConst = EntryIter::reference;
using PickKeyIter = _MapSubSelector<EntryIter,DetectConst>::PickKey;
using PickValIter = _MapSubSelector<EntryIter,DetectConst>::PickVal;
using KeyIter = RangeIter<PickKeyIter>;
using ValIter = RangeIter<PickValIter>;
@ -239,12 +239,12 @@ namespace iter_stl {
{
using EntryIter = IT;
using KeyType = typename EntryIter::value_type::first_type;
using ValType = typename EntryIter::value_type::second_type;
using KeyType = EntryIter::value_type::first_type;
using ValType = EntryIter::value_type::second_type;
using DetectConst = typename EntryIter::reference;
using PickKeyIter = typename _MapSubSelector<EntryIter,DetectConst>::PickKey;
using PickValIter = typename _MapSubSelector<EntryIter,DetectConst>::PickVal;
using DetectConst = EntryIter::reference;
using PickKeyIter = _MapSubSelector<EntryIter,DetectConst>::PickKey;
using PickValIter = _MapSubSelector<EntryIter,DetectConst>::PickVal;
using KeyIter = RangeIter<PickKeyIter>;
using ValIter = RangeIter<PickValIter>;
@ -257,7 +257,7 @@ namespace iter_stl {
template<class SEQ>
struct _SeqT
{
using Iter = typename SEQ::iterator;
using Iter = SEQ::iterator;
using Range = RangeIter<Iter>;
using DistinctVals = DistinctIter<Range>;
using Addrs = AddressExposingIter<Range>;
@ -266,7 +266,7 @@ namespace iter_stl {
template<class SEQ>
struct _SeqT<const SEQ>
{
using Iter = typename SEQ::const_iterator;
using Iter = SEQ::const_iterator;
using Range = RangeIter<Iter>;
using DistinctVals = DistinctIter<Range>;
using Addrs = AddressExposingIter<Range>;
@ -281,10 +281,10 @@ namespace iter_stl {
* to yield each Element from a STL container
*/
template<class CON>
inline typename _SeqT<CON>::Range
inline _SeqT<CON>::Range
eachElm (CON& coll)
{
using Range = typename _SeqT<CON>::Range;
using Range = _SeqT<CON>::Range;
return Range (coll.begin(), coll.end());
}
@ -293,10 +293,10 @@ namespace iter_stl {
* exposing the address of each Element within a STL
*/
template<class CON>
inline typename _SeqT<CON>::Addrs
inline _SeqT<CON>::Addrs
eachAddress (CON& coll)
{
using Addresses = typename _SeqT<CON>::Addrs;
using Addresses = _SeqT<CON>::Addrs;
return Addresses (eachElm (coll));
}
@ -305,11 +305,11 @@ namespace iter_stl {
* each key of a map/multimap
*/
template<class MAP>
inline typename _MapT<MAP>::KeyIter
inline _MapT<MAP>::KeyIter
eachKey (MAP& map)
{
using Range = typename _MapT<MAP>::KeyIter;
using PickKey = typename _MapT<MAP>::PickKeyIter;
using Range = _MapT<MAP>::KeyIter;
using PickKey = _MapT<MAP>::PickKeyIter;
return Range (PickKey (map.begin()), PickKey (map.end()));
}
@ -319,11 +319,11 @@ namespace iter_stl {
* from a given range of (key,value) pairs
*/
template<class IT>
inline typename _MapIterT<IT>::KeyIter
inline _MapIterT<IT>::KeyIter
eachKey (IT const& begin, IT const& end)
{
using Range = typename _MapIterT<IT>::KeyIter;
using PickKey = typename _MapIterT<IT>::PickKeyIter;
using Range = _MapIterT<IT>::KeyIter;
using PickKey = _MapIterT<IT>::PickKeyIter;
return Range (PickKey (begin), PickKey (end));
}
@ -333,11 +333,11 @@ namespace iter_stl {
* each value within a map/multimap
*/
template<class MAP>
inline typename _MapT<MAP>::ValIter
inline _MapT<MAP>::ValIter
eachVal (MAP& map)
{
using Range = typename _MapT<MAP>::ValIter;
using PickVal = typename _MapT<MAP>::PickValIter;
using Range = _MapT<MAP>::ValIter;
using PickVal = _MapT<MAP>::PickValIter;
return Range (PickVal (map.begin()), PickVal (map.end()));
}
@ -347,11 +347,11 @@ namespace iter_stl {
* from a given range of (key,value) pairs
*/
template<class IT>
inline typename _MapIterT<IT>::ValIter
inline _MapIterT<IT>::ValIter
eachVal (IT const& begin, IT const& end)
{
using Range = typename _MapIterT<IT>::ValIter;
using PickVal = typename _MapIterT<IT>::PickValIter;
using Range = _MapIterT<IT>::ValIter;
using PickVal = _MapIterT<IT>::PickValIter;
return Range (PickVal (begin), PickVal (end));
}
@ -361,11 +361,11 @@ namespace iter_stl {
* any repetitions in the given sequence.
*/
template<class SEQ>
inline typename _SeqT<SEQ>::DistinctVals
inline _SeqT<SEQ>::DistinctVals
eachDistinct (SEQ& seq)
{
using Range = typename _SeqT<SEQ>::Range;
using DistinctValues = typename _SeqT<SEQ>::DistinctVals;
using Range = _SeqT<SEQ>::Range;
using DistinctValues = _SeqT<SEQ>::DistinctVals;
return DistinctValues (Range (seq.begin(), seq.end()));
}
@ -376,7 +376,7 @@ namespace iter_stl {
* @warning full scan of all keys, dropping repetitions
*/
template<class MAP>
inline typename _MapT<MAP>::DistinctKeys
inline _MapT<MAP>::DistinctKeys
eachDistinctKey (MAP& map)
{
return typename _MapT<MAP>::DistinctKeys (eachKey (map));
@ -388,12 +388,12 @@ namespace iter_stl {
* @warning full scan of all keys, dropping repetitions
*/
template<class MMAP, typename KEY>
inline typename _MapT<MMAP>::ValIter
inline _MapT<MMAP>::ValIter
eachValForKey (MMAP& multimap, KEY key)
{
using Pos = typename _MapT<MMAP>::EntryIter;
using Range = typename _MapT<MMAP>::ValIter;
using PickVal = typename _MapT<MMAP>::PickValIter;
using Pos = _MapT<MMAP>::EntryIter;
using Range = _MapT<MMAP>::ValIter;
using PickVal = _MapT<MMAP>::PickValIter;
std::pair<Pos,Pos> valRange = multimap.equal_range (key);

View file

@ -212,9 +212,9 @@ namespace lib {
using _ValTrait = meta::ValueTypeBinding<std::remove_pointer_t<POS>>;
public:
using value_type = typename _ValTrait::value_type;
using reference = typename _ValTrait::reference;
using pointer = typename _ValTrait::pointer;
using value_type = _ValTrait::value_type;
using reference = _ValTrait::reference;
using pointer = _ValTrait::pointer;
IterAdapter (CON src, POS const& startpos)
@ -302,7 +302,7 @@ namespace lib {
protected:
using ConRef = typename meta::RefTraits<CON>::Reference;
using ConRef = meta::RefTraits<CON>::Reference;
/** allow derived classes to access backing container */
ConRef source() { return source_; }
@ -376,9 +376,9 @@ namespace lib {
ST core_;
public:
using value_type = typename meta::RefTraits<T>::Value;
using reference = typename meta::RefTraits<T>::Reference;
using pointer = typename meta::RefTraits<T>::Pointer;
using value_type = meta::RefTraits<T>::Value;
using reference = meta::RefTraits<T>::Reference;
using pointer = meta::RefTraits<T>::Pointer;
IterStateWrapper (ST&& initialState)
: core_(std::forward<ST>(initialState))
@ -519,7 +519,7 @@ namespace lib {
return bool(srcIter());
}
typename IT::reference
IT::reference
yield() const
{
return *srcIter();
@ -614,7 +614,7 @@ namespace lib {
class ContainerCore
: public CON
{
using Iter = typename CON::iterator;
using Iter = CON::iterator;
Iter p_;
@ -694,9 +694,9 @@ namespace lib {
public:
using YieldRes = iter::CoreYield<COR>;
using value_type = typename meta::RefTraits<YieldRes>::Value;
using reference = typename meta::RefTraits<YieldRes>::Reference;
using pointer = typename meta::RefTraits<YieldRes>::Pointer;
using value_type = meta::RefTraits<YieldRes>::Value;
using reference = meta::RefTraits<YieldRes>::Reference;
using pointer = meta::RefTraits<YieldRes>::Pointer;
/** by default, pass anything down for initialisation of the core.
@ -803,11 +803,11 @@ namespace lib {
using _ValTrait = meta::ValueTypeBinding<meta::remove_pointer_t<IT>>;
public:
using pointer = typename _ValTrait::pointer;
using reference = typename _ValTrait::reference;
using pointer = _ValTrait::pointer;
using reference = _ValTrait::reference;
/// @note special twist, since a STL const_iterator would yield a non-const `value_type`
using value_type = typename std::remove_reference<reference>::type;
using value_type = std::remove_reference<reference>::type;
RangeIter (IT const& start, IT const& end)
@ -1052,7 +1052,7 @@ namespace lib {
template<class T2>
struct SimilarIter ///< rebind to rewritten Iterator wrapped into RangeIter
{
using WrappedIter = typename IterType<IT>::template SimilarIter<T2>::Type;
using WrappedIter = IterType<IT>::template SimilarIter<T2>::Type;
using Type = RangeIter<WrappedIter>;
};
};
@ -1067,9 +1067,9 @@ namespace lib {
public:
using value_type = const typename IT::value_type;
using pointer = const typename IT::pointer ;
using reference = const typename IT::reference ;
using value_type = const IT::value_type;
using pointer = const IT::pointer ;
using reference = const IT::reference ;
ConstIter (IT srcIter)
: i_(srcIter)

View file

@ -150,11 +150,11 @@ namespace iter {
: public _IterChainSetup<SRC>::Pipeline
{
using _Trait = _IterChainSetup<SRC>;
using _Base = typename _Trait::Pipeline;
using _Base = _Trait::Pipeline;
using Value = typename _Base::value_type;
using Filter = typename _Trait::Filter;
using Step = typename _Trait::StepFunctor;
using Value = _Base::value_type;
using Filter = _Trait::Filter;
using Step = _Trait::StepFunctor;
/** Storage for a sequence of filter configuration functors */
std::vector<Step> stepChain_;

View file

@ -56,9 +56,9 @@ namespace lib {
public:
using pointer = typename meta::ValueTypeBinding<IT>::pointer;
using reference = typename meta::ValueTypeBinding<IT>::reference;
using value_type = typename std::remove_reference<reference>::type; ///< @note will be const for const iterators (while const_iterator::value_type isn't)
using pointer = meta::ValueTypeBinding<IT>::pointer;
using reference = meta::ValueTypeBinding<IT>::reference;
using value_type = std::remove_reference<reference>::type; ///< @note will be const for const iterators (while const_iterator::value_type isn't)
CursorGear()

View file

@ -133,9 +133,9 @@ namespace lib {
namespace iter_explorer { // basic iterator wrappers...
template<class CON>
using iterator = typename meta::Strip<CON>::TypeReferred::iterator;
using iterator = meta::Strip<CON>::TypeReferred::iterator;
template<class CON>
using const_iterator = typename meta::Strip<CON>::TypeReferred::const_iterator;
using const_iterator = meta::Strip<CON>::TypeReferred::const_iterator;
/**
* Adapt STL compliant container.
@ -190,7 +190,7 @@ namespace lib {
class IterSourceIter
: public ISO::iterator
{
using Iterator = typename ISO::iterator;
using Iterator = ISO::iterator;
public:
IterSourceIter() =default;
@ -273,8 +273,8 @@ namespace lib {
template<class SRC>
struct _DecoratorTraits<SRC, enable_if<is_StateCore<SRC>>>
{
using SrcRaw = typename lib::meta::Strip<SRC>::Type;
using SrcVal = typename meta::RefTraits<iter::CoreYield<SrcRaw>>::Value;
using SrcRaw = lib::meta::Strip<SRC>::Type;
using SrcVal = meta::RefTraits<iter::CoreYield<SrcRaw>>::Value;
using SrcIter = lib::IterableDecorator<lib::CheckedCore<SrcRaw>>;
};
@ -282,7 +282,7 @@ namespace lib {
struct _DecoratorTraits<SRC, enable_if<shall_use_Lumiera_Iter<SRC>>>
{
using SrcIter = remove_reference_t<SRC>;
using SrcVal = typename SrcIter::value_type;
using SrcVal = SrcIter::value_type;
};
template<class SRC>
@ -291,14 +291,14 @@ namespace lib {
static_assert (not std::is_rvalue_reference<SRC>::value,
"container needs to exist elsewhere during the lifetime of the iteration");
using SrcIter = iter_explorer::StlRange<SRC>;
using SrcVal = typename SrcIter::value_type;
using SrcVal = SrcIter::value_type;
};
template<class ISO>
struct _DecoratorTraits<ISO*, enable_if<is_base_of<IterSource<typename ISO::value_type>, ISO>>>
{
using SrcIter = iter_explorer::IterSourceIter<ISO>;
using SrcVal = typename ISO::value_type;
using SrcVal = ISO::value_type;
};
template<class ISO>
@ -324,7 +324,7 @@ namespace lib {
template<class SRC, class RES>
struct _ExpanderTraits
{
using ResIter = typename _DecoratorTraits<RES>::SrcIter;
using ResIter = _DecoratorTraits<RES>::SrcIter;
using SrcYield = iter::Yield<SRC>;
using ResYield = iter::Yield<ResIter>;
using _CommonT = meta::CommonResultYield<SrcYield,ResYield>;
@ -336,10 +336,10 @@ namespace lib {
static_assert (is_const_v<SrcYield> == is_const_v<ResYield>,
"source and expanded types differ in const-ness");
using YieldRes = typename _CommonT::ResType;
using value_type = typename _CommonT::value_type;
using reference = typename _CommonT::reference;
using pointer = typename _CommonT::pointer;
using YieldRes = _CommonT::ResType;
using value_type = _CommonT::value_type;
using reference = _CommonT::reference;
using pointer = _CommonT::pointer;
};
}//(End) IterExplorer traits
@ -389,22 +389,22 @@ namespace lib {
template<typename F, typename SEL =void>
struct FunDetector
{
using Sig = typename _Fun<F>::Sig;
using Sig = _Fun<F>::Sig;
};
/** handle a generic lambda, accepting a reference to the `SRC` iterator */
template<typename F>
struct FunDetector<F, disable_if<_Fun<F>> >
{
using Arg = typename std::add_lvalue_reference<SRC>::type;
using Arg = std::add_lvalue_reference<SRC>::type;
using Ret = decltype(std::declval<F>() (std::declval<Arg>()));
using Sig = Ret(Arg);
};
using Sig = typename FunDetector<FUN>::Sig;
using Arg = typename _Fun<Sig>::Args::List::Head; // assuming function with a single argument
using Res = typename _Fun<Sig>::Ret;
using Sig = FunDetector<FUN>::Sig;
using Arg = _Fun<Sig>::Args::List::Head; // assuming function with a single argument
using Res = _Fun<Sig>::Ret;
static_assert (meta::is_UnaryFun<Sig>());
@ -442,7 +442,7 @@ namespace lib {
, is_base_of<IterSource<typename IT::value_type>, remove_reference_t<Arg>>
> >>
{
using Source = typename IT::Source;
using Source = IT::Source;
static auto
wrap (function<Sig> rawFun) ///< extract the (abstracted) IterSource
@ -466,7 +466,7 @@ namespace lib {
inline void
static_assert_isPredicate()
{
using Res = typename _FunTraits<FUN,SRC>::Res;
using Res = _FunTraits<FUN,SRC>::Res;
static_assert(std::is_constructible<bool, Res>::value, "Functor must be a predicate");
}
@ -477,8 +477,8 @@ namespace lib {
template<class SRC, class FUN>
struct _ReduceTraits
{
using Result = typename iter_explorer::_FunTraits<FUN,SRC>::Res;
using ResVal = typename lib::meta::RefTraits<Result>::Value;
using Result = iter_explorer::_FunTraits<FUN,SRC>::Res;
using ResVal = lib::meta::RefTraits<Result>::Value;
};
@ -557,7 +557,7 @@ namespace lib {
static_assert(can_IterForEach<SRC>::value, "Lumiera Iterator required as source");
using _Trait = _ExpanderTraits<SRC,RES>;
using ResIter = typename _Trait::ResIter;
using ResIter = _Trait::ResIter;
using RootExpandFunctor = function<RES(SRC&)>;
using ChldExpandFunctor = function<RES(ResIter&)>;
@ -621,10 +621,10 @@ namespace lib {
public: /* === Iteration control API for IterableDecorator === */
/** @note result type bindings based on a common type of source and expanded result */
using YieldRes = typename _Trait::YieldRes;
using value_type = typename _Trait::value_type;
using reference = typename _Trait::reference;
using pointer = typename _Trait::pointer;
using YieldRes = _Trait::YieldRes;
using value_type = _Trait::value_type;
using reference = _Trait::reference;
using pointer = _Trait::pointer;
bool
@ -791,9 +791,9 @@ namespace lib {
TransformedItem treated_;
public:
using value_type = typename meta::ValueTypeBinding<RES>::value_type;
using reference = typename meta::ValueTypeBinding<RES>::reference;
using pointer = typename meta::ValueTypeBinding<RES>::pointer;
using value_type = meta::ValueTypeBinding<RES>::value_type;
using reference = meta::ValueTypeBinding<RES>::reference;
using pointer = meta::ValueTypeBinding<RES>::pointer;
template<typename FUN>
@ -896,7 +896,7 @@ namespace lib {
protected:
using Group = std::array<RES, grp>;
using Iter = typename Group::iterator;
using Iter = Group::iterator;
struct Buffer
: lib::UninitialisedStorage<RES,grp>
{
@ -1028,7 +1028,7 @@ namespace lib {
static_assert(can_IterForEach<SRC>::value, "Lumiera Iterator required as source");
protected:
using SrcValue = typename meta::ValueTypeBinding<SRC>::value_type;
using SrcValue = meta::ValueTypeBinding<SRC>::value_type;
using Grouping = function<GRP(SRC&)>;
using Aggregator = function<void(AGG&, SrcValue&)>;
@ -1038,9 +1038,9 @@ namespace lib {
Aggregator aggregate_;
public:
using value_type = typename meta::RefTraits<AGG>::Value;
using reference = typename meta::RefTraits<AGG>::Reference;
using pointer = typename meta::RefTraits<AGG>::Pointer;
using value_type = meta::RefTraits<AGG>::Value;
using reference = meta::RefTraits<AGG>::Reference;
using pointer = meta::RefTraits<AGG>::Pointer;
GroupAggregator() =default;
// inherited default copy operations
@ -1152,7 +1152,7 @@ namespace lib {
return bool(srcIter());
}
typename SRC::reference
SRC::reference
yield() const
{
return *srcIter();
@ -1446,7 +1446,7 @@ namespace lib {
, public ChildExpandableSource<typename SRC::value_type>
{
using Parent = WrappedLumieraIter<SRC>;
using Val = typename SRC::value_type; ///////////////////////////////////TICKET #1125 : get rid of Val
using Val = SRC::value_type; ///////////////////////////////////TICKET #1125 : get rid of Val
~PackagedIterExplorerSource() { }
public:
@ -1583,9 +1583,9 @@ namespace lib {
public:
using value_type = typename meta::ValueTypeBinding<SRC>::value_type;
using reference = typename meta::ValueTypeBinding<SRC>::reference;
using pointer = typename meta::ValueTypeBinding<SRC>::pointer;
using value_type = meta::ValueTypeBinding<SRC>::value_type;
using reference = meta::ValueTypeBinding<SRC>::reference;
using pointer = meta::ValueTypeBinding<SRC>::pointer;
using TAG_IterExplorer_Src = SRC; ///< @internal for \ref _PipelineDetector
@ -1640,10 +1640,10 @@ namespace lib {
auto
expand (FUN&& expandFunctor)
{
using ExpandedChildren = typename iter_explorer::_FunTraits<FUN,SRC>::Res;
using ExpandedChildren = iter_explorer::_FunTraits<FUN,SRC>::Res;
using ResCore = iter_explorer::Expander<SRC, ExpandedChildren>;
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
using ResIter = _DecoratorTraits<ResCore>::SrcIter;
return IterExplorer<ResIter> (ResCore {move(*this), forward<FUN>(expandFunctor)});
}
@ -1664,7 +1664,7 @@ namespace lib {
expandAll()
{
using ResCore = iter_explorer::AutoExpander<SRC>;
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
using ResIter = _DecoratorTraits<ResCore>::SrcIter;
return IterExplorer<ResIter> (ResCore {move(*this)});
}
@ -1692,7 +1692,7 @@ namespace lib {
expandOnIteration()
{
using ResCore = iter_explorer::ScheduledExpander<SRC>;
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
using ResIter = _DecoratorTraits<ResCore>::SrcIter;
return IterExplorer<ResIter> (ResCore {move(*this)});
}
@ -1712,10 +1712,10 @@ namespace lib {
auto
transform (FUN&& transformFunctor)
{
using Product = typename iter_explorer::_FunTraits<FUN,SRC>::Res;
using Product = iter_explorer::_FunTraits<FUN,SRC>::Res;
using ResCore = iter_explorer::Transformer<SRC, Product>;
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
using ResIter = _DecoratorTraits<ResCore>::SrcIter;
return IterExplorer<ResIter> (ResCore {move(*this), forward<FUN>(transformFunctor)});
}
@ -1733,9 +1733,9 @@ namespace lib {
auto
grouped()
{
using Value = typename meta::ValueTypeBinding<SRC>::value_type;
using Value = meta::ValueTypeBinding<SRC>::value_type;
using ResCore = iter_explorer::Grouping<SRC, Value, grp>;
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
using ResIter = _DecoratorTraits<ResCore>::SrcIter;
return IterExplorer<ResIter> (ResCore {move(*this)});
}
@ -1756,14 +1756,14 @@ namespace lib {
auto
groupedBy (FGRP&& groupFun, FAGG&& aggFun)
{
using GroupVal = typename iter_explorer::_FunTraits<FGRP,SRC>::Res;
using GroupVal = iter_explorer::_FunTraits<FGRP,SRC>::Res;
static_assert (meta::is_BinaryFun<FAGG>());
using ArgType1 = typename _Fun<FAGG>::Args::List::Head;
using Aggregate = typename meta::RefTraits<ArgType1>::Value;
using ArgType1 = _Fun<FAGG>::Args::List::Head;
using Aggregate = meta::RefTraits<ArgType1>::Value;
using ResCore = iter_explorer::GroupAggregator<SRC, Aggregate, GroupVal>;
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
using ResIter = _DecoratorTraits<ResCore>::SrcIter;
return IterExplorer<ResIter> (ResCore {move(*this)
,forward<FGRP> (groupFun)
@ -1775,7 +1775,7 @@ namespace lib {
auto
groupedBy (FGRP&& groupFun)
{
using Value = typename meta::ValueTypeBinding<SRC>::value_type;
using Value = meta::ValueTypeBinding<SRC>::value_type;
return groupedBy (forward<FGRP> (groupFun)
,[](Value& agg, Value const& val){ agg += val; }
);
@ -1792,7 +1792,7 @@ namespace lib {
iter_explorer::static_assert_isPredicate<FUN,SRC>();
using ResCore = iter_explorer::StopTrigger<SRC>;
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
using ResIter = _DecoratorTraits<ResCore>::SrcIter;
return IterExplorer<ResIter> (ResCore {move(*this), forward<FUN>(whileCond)});
}
@ -1808,8 +1808,8 @@ namespace lib {
iter_explorer::static_assert_isPredicate<FUN,SRC>();
using ResCore = iter_explorer::StopTrigger<SRC>;
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
using ArgType = typename iter_explorer::_FunTraits<FUN,SRC>::Arg;
using ResIter = _DecoratorTraits<ResCore>::SrcIter;
using ArgType = iter_explorer::_FunTraits<FUN,SRC>::Arg;
return IterExplorer<ResIter> (ResCore { move(*this)
,[whileCond = forward<FUN>(untilCond)](ArgType val)
@ -1833,7 +1833,7 @@ namespace lib {
iter_explorer::static_assert_isPredicate<FUN,SRC>();
using ResCore = iter_explorer::Filter<SRC>;
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
using ResIter = _DecoratorTraits<ResCore>::SrcIter;
return IterExplorer<ResIter> (ResCore {move(*this), forward<FUN>(filterPredicate)});
}
@ -1863,7 +1863,7 @@ namespace lib {
iter_explorer::static_assert_isPredicate<FUN,SRC>();
using ResCore = iter_explorer::MutableFilter<SRC>;
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
using ResIter = _DecoratorTraits<ResCore>::SrcIter;
return IterExplorer<ResIter> (ResCore {move(*this), forward<FUN>(filterPredicate)});
}
@ -1893,7 +1893,7 @@ namespace lib {
processingLayer()
{
using ResCore = LAY<SRC>;
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
using ResIter = _DecoratorTraits<ResCore>::SrcIter;
return IterExplorer<ResIter> (ResCore {move(*this)});
}
@ -1904,7 +1904,7 @@ namespace lib {
auto
asPtr()
{
using Val = typename meta::ValueTypeBinding<SRC>::value_type;
using Val = meta::ValueTypeBinding<SRC>::value_type;
static_assert (not std::is_pointer_v<Val>);
return IterExplorer::transform ([](Val& ref){ return &ref; });
}
@ -1913,7 +1913,7 @@ namespace lib {
auto
derefPtr()
{
using Ptr = typename meta::ValueTypeBinding<SRC>::value_type;
using Ptr = meta::ValueTypeBinding<SRC>::value_type;
return IterExplorer::transform ([](Ptr ptr){ return *ptr; });
}
@ -1925,9 +1925,9 @@ namespace lib {
auto
deduplicate()
{
using Value = typename meta::ValueTypeBinding<SRC>::value_type;
using Value = meta::ValueTypeBinding<SRC>::value_type;
using ResCore = ContainerCore<SET<Value>>;
using ResIter = typename _DecoratorTraits<ResCore>::SrcIter;
using ResIter = _DecoratorTraits<ResCore>::SrcIter;
SET<Value> buffer;
for (auto& val : *this)
buffer.emplace (val);
@ -2106,7 +2106,7 @@ namespace lib {
template<class COR> // used when actually a CheckedCore was attached
struct _UnstripAdapter<COR, std::void_t<typename COR::TAG_CheckedCore_Raw> >
{
using RawIter = typename COR::TAG_CheckedCore_Raw;
using RawIter = COR::TAG_CheckedCore_Raw;
};
@ -2123,8 +2123,8 @@ namespace lib {
template<class SRC>
struct _PipelineDetector<SRC, std::void_t<typename SRC::TAG_IterExplorer_Src> >
{
using _SrcIT = typename SRC::TAG_IterExplorer_Src;
using RawIter = typename _UnstripAdapter<_SrcIT>::RawIter;
using _SrcIT = SRC::TAG_IterExplorer_Src;
using RawIter = _UnstripAdapter<_SrcIT>::RawIter;
};
}//(End)internal adapter logic
@ -2188,9 +2188,9 @@ namespace lib {
inline auto
explore (IT&& srcSeq)
{
using RawIter = typename _PipelineDetector<IT>::RawIter; // possibly strip an underlying IterExplorer
using SrcIter = typename _DecoratorTraits<RawIter>::SrcIter; // then decide how to adapt the source / iterator
using Base = typename _BaseDetector<SrcIter>::BaseAdapter; // detect if a BaseAdapter exists or must be added
using RawIter = _PipelineDetector<IT>::RawIter; // possibly strip an underlying IterExplorer
using SrcIter = _DecoratorTraits<RawIter>::SrcIter; // then decide how to adapt the source / iterator
using Base = _BaseDetector<SrcIter>::BaseAdapter; // detect if a BaseAdapter exists or must be added
return IterExplorer<Base> (std::forward<IT> (srcSeq));
}

View file

@ -206,7 +206,7 @@ namespace lib {
/** storage for the empty data-source constant */
template<typename TY>
typename IterSource<TY>::iterator IterSource<TY>::EMPTY_SOURCE = iterator();
IterSource<TY>::iterator IterSource<TY>::EMPTY_SOURCE = iterator();
@ -226,7 +226,7 @@ namespace lib {
IT src_;
protected:
using Pos = typename ISO::Pos;
using Pos = ISO::Pos;
Pos ////////////////////////////////////////////////////TICKET #1125 : this API should use three control functions, similar to IterStateWrapper
firstResult ()
@ -276,55 +276,55 @@ namespace lib {
template<class CON>
struct _SeqT
{
using Val = typename CON::iterator::value_type;
using Iter = typename IterSource<Val>::iterator;
using Val = CON::iterator::value_type;
using Iter = IterSource<Val>::iterator;
};
template<class IT>
struct _RangeT
{
using Val = typename IT::value_type;
using Iter = typename IterSource<Val>::iterator;
using Val = IT::value_type;
using Iter = IterSource<Val>::iterator;
};
template<class MAP>
struct _MapT
{
using Key = typename MAP::key_type;
using Val = typename MAP::value_type::second_type;
using KeyIter = typename IterSource<Key>::iterator;
using ValIter = typename IterSource<Val>::iterator;
using Key = MAP::key_type;
using Val = MAP::value_type::second_type;
using KeyIter = IterSource<Key>::iterator;
using ValIter = IterSource<Val>::iterator;
};
template<class IT>
struct _IterT
{
using Src = typename std::remove_reference<IT>::type;
using Val = typename Src::value_type;
using Iter = typename IterSource<Val>::iterator;
using Src = std::remove_reference<IT>::type;
using Val = Src::value_type;
using Iter = IterSource<Val>::iterator;
};
template<class IT, class FUN>
struct _TransformIterT
{
using Src = typename std::remove_reference<IT>::type;
using ResVal = typename lib::meta::_Fun<FUN>::Ret;
using Src = std::remove_reference<IT>::type;
using ResVal = lib::meta::_Fun<FUN>::Ret;
using TransIter = TransformIter<Src, ResVal>;
using Iter = typename IterSource<ResVal>::iterator;
using Iter = IterSource<ResVal>::iterator;
};
template<class IT>
struct _PairIterT
{
using Src = typename std::remove_reference<IT>::type;
using PairType = typename Src::value_type;
using ValType = typename PairType::second_type;
using ConstKeyType = typename PairType::first_type;
using Src = std::remove_reference<IT>::type;
using PairType = Src::value_type;
using ValType = PairType::second_type;
using ConstKeyType = PairType::first_type;
// since we're returning the keys always by value,
// we can strip the const added by the STL map types
using KeyType = typename std::remove_const<ConstKeyType>::type;
using KeyType = std::remove_const<ConstKeyType>::type;
using KeyIter = TransformIter<Src, KeyType>;
using ValIter = TransformIter<Src, ValType>;
@ -335,14 +335,14 @@ namespace lib {
template<class IT>
typename _PairIterT<IT>::KeyIter
_PairIterT<IT>::KeyIter
takePairFirst (IT&& source)
{
return transformIterator(forward<IT>(source), _PairIterT<IT>::takeFirst );
}
template<class IT>
typename _PairIterT<IT>::ValIter
_PairIterT<IT>::ValIter
takePairSecond (IT&& source)
{
return transformIterator(forward<IT>(source), _PairIterT<IT>::takeSecond );
@ -356,11 +356,11 @@ namespace lib {
* exposing just a IterSource based frontend.
*/
template<class IT>
typename _IterT<IT>::Iter
_IterT<IT>::Iter
wrapIter (IT&& source)
{
using Src = typename _IterT<IT>::Src;
using Val = typename _IterT<IT>::Val;
using Src = _IterT<IT>::Src;
using Val = _IterT<IT>::Val;
return IterSource<Val>::build (new WrappedLumieraIter<Src> (forward<IT>(source)));
}
@ -376,7 +376,7 @@ namespace lib {
singleVal (VAL&& something)
{
using Src = decltype(singleValIterator (forward<VAL>(something)));
using Val = typename _IterT<Src>::Val;
using Val = _IterT<Src>::Val;
return IterSource<Val>::build (new WrappedLumieraIter<Src>{singleValIterator (forward<VAL>(something))});
}
@ -392,11 +392,11 @@ namespace lib {
* function call for every fetched element.
*/
template<class IT, class FUN>
typename _TransformIterT<IT,FUN>::Iter
_TransformIterT<IT,FUN>::Iter
transform (IT&& source, FUN processingFunc)
{
using ValType = typename _TransformIterT<IT,FUN>::ResVal;
using TransIT = typename _TransformIterT<IT,FUN>::TransIter;
using ValType = _TransformIterT<IT,FUN>::ResVal;
using TransIT = _TransformIterT<IT,FUN>::TransIter;
return IterSource<ValType>::build (
new WrappedLumieraIter<TransIT> (
@ -408,7 +408,7 @@ namespace lib {
* all the keys of the given Map or Hashtable
*/
template<class MAP>
typename _MapT<MAP>::KeyIter
_MapT<MAP>::KeyIter
eachMapKey (MAP& map)
{
using Range = RangeIter<typename MAP::iterator>;
@ -422,7 +422,7 @@ namespace lib {
* all the values of the given Map or Hashtable
*/
template<class MAP>
typename _MapT<MAP>::ValIter
_MapT<MAP>::ValIter
eachMapVal (MAP& map)
{
using Range = RangeIter<typename MAP::iterator>;
@ -438,7 +438,7 @@ namespace lib {
* the distinct keys
*/
template<class MAP>
typename _MapT<MAP>::KeyIter
_MapT<MAP>::KeyIter
eachDistinctKey (MAP& map)
{
using Range = RangeIter<typename MAP::iterator>;
@ -453,10 +453,10 @@ namespace lib {
* @note obviously in case of a Map we'll get at most one result.
*/
template<class MAP>
typename _MapT<MAP>::ValIter
_MapT<MAP>::ValIter
eachValForKey (MAP& map, typename _MapT<MAP>::Key key)
{
using Pos = typename MAP::iterator;
using Pos = MAP::iterator;
using Range = RangeIter<Pos>;
std::pair<Pos,Pos> valuesForKey = map.equal_range(key);
@ -472,10 +472,10 @@ namespace lib {
* starting with \c begin and excluding \c end .
*/
template<class CON>
typename _SeqT<CON>::Iter
_SeqT<CON>::Iter
eachEntry (CON& container)
{
using ValType = typename _SeqT<CON>::Val;
using ValType = _SeqT<CON>::Val;
using Range = RangeIter<typename CON::iterator>;
Range contents (container.begin(), container.end());
@ -487,10 +487,10 @@ namespace lib {
* defined by a classical Iterator range.
*/
template<class IT>
typename _RangeT<IT>::Iter
_RangeT<IT>::Iter
eachEntry (IT const& begin, IT const& end)
{
using ValType = typename _RangeT<IT>::Val;
using ValType = _RangeT<IT>::Val;
using Range = RangeIter<IT>;
Range contents (begin, end);

View file

@ -51,7 +51,7 @@ namespace lib {
* Building block for a tupeled-iterator.
* exposes the iterator API lifted to the product type (tuple).
*/
template<class ITUP>
template<meta::tuple_like ITUP>
class ProductCore
{
ITUP iters_;
@ -76,8 +76,8 @@ namespace lib {
bool
checkPoint() const
{ //note: short-circuit
return std::apply ([](auto&... its) { return (bool(its) and ...); }
, iters_);
return meta::apply ([](auto&... its) { return (bool(its) and ...); }
, iters_);
}
ITUP&
@ -137,7 +137,7 @@ namespace lib {
inline auto
zip (ITS&& ...iters)
{
auto access_result = [](auto& it)->decltype(auto){ return *it; }; // Note: pass-through result type (maybe reference)
auto access_result = [ ](auto& it)->decltype(auto){ return *it; }; // Note: pass-through result type (maybe reference)
auto tuple_results = [&](auto& it){ return meta::mapEach (*it, access_result); };
//
auto core = iter::ProductCore{iter::buildIterTuple (std::forward<ITS> (iters)...)};

View file

@ -137,9 +137,9 @@ namespace lib {
return bool(source_);
}
using pointer = typename IT::pointer;
using reference = typename IT::reference;
using value_type = typename IT::value_type;
using pointer = IT::pointer;
using reference = IT::reference;
using value_type = IT::value_type;
};
@ -186,9 +186,9 @@ namespace lib {
public:
using pointer = typename CORE::pointer;
using reference = typename CORE::reference;
using value_type = typename CORE::value_type;
using pointer = CORE::pointer;
using reference = CORE::reference;
using value_type = CORE::value_type;
IterTool (CORE&& setup)
@ -341,7 +341,7 @@ namespace lib {
typedef IterTool<_Filter> _Impl;
public:
static bool acceptAll(typename _Filter::Val) { return true; }
static bool acceptAll(_Filter::Val) { return true; }
FilterIter ()
@ -378,7 +378,7 @@ namespace lib {
inline auto
filterIterator (IT&& src, PRED filterPredicate)
{
using SrcIT = typename std::remove_reference<IT>::type;
using SrcIT = std::remove_reference<IT>::type;
return FilterIter<SrcIT>{forward<IT>(src), filterPredicate};
}
@ -411,7 +411,7 @@ namespace lib {
: public FilterIter<IT>
{
using _Filter = FilterCore<IT>;
using Val = typename _Filter::Val;
using Val = _Filter::Val;
void
reEvaluate()
@ -739,9 +739,9 @@ namespace lib {
return bool(source_);
}
using pointer = typename ValueTypeBinding<VAL>::pointer;
using reference = typename ValueTypeBinding<VAL>::reference;
using value_type = typename ValueTypeBinding<VAL>::value_type;
using pointer = ValueTypeBinding<VAL>::pointer;
using reference = ValueTypeBinding<VAL>::reference;
using value_type = ValueTypeBinding<VAL>::value_type;
};
@ -787,7 +787,7 @@ namespace lib {
inline auto
transformIterator (IT const& src, FUN processingFunc)
{
using OutVal = typename lib::meta::_Fun<FUN>::Ret;
using OutVal = lib::meta::_Fun<FUN>::Ret;
return TransformIter<IT,OutVal>{src,processingFunc};
}
@ -795,8 +795,8 @@ namespace lib {
inline auto
transformIterator (IT&& src, FUN processingFunc)
{
using SrcIT = typename std::remove_reference<IT>::type;
using OutVal = typename lib::meta::_Fun<FUN>::Ret;
using SrcIT = std::remove_reference<IT>::type;
using OutVal = lib::meta::_Fun<FUN>::Ret;
return TransformIter<SrcIT,OutVal>{forward<IT>(src), processingFunc};
}
@ -815,10 +815,10 @@ namespace lib {
template<class IT>
inline typename IT::value_type
inline IT::value_type
pull_last (IT iter)
{
using Val = typename IT::value_type;
using Val = IT::value_type;
using Item = wrapper::ItemWrapper<Val>;
Item lastElm;
@ -845,7 +845,7 @@ namespace lib {
inline auto
filterRepetitions (IT const& source)
{
using Val = typename meta::ValueTypeBinding<IT>::value_type;
using Val = meta::ValueTypeBinding<IT>::value_type;
return filterIterator (source, SkipRepetition<Val>());
}
@ -853,7 +853,7 @@ namespace lib {
inline auto
filterRepetitions (IT&& source)
{
using Val = typename meta::ValueTypeBinding<IT>::value_type;
using Val = meta::ValueTypeBinding<IT>::value_type;
return filterIterator (forward<IT>(source), SkipRepetition<Val>() );
}

View file

@ -179,7 +179,7 @@ namespace lib {
generateTrap (DEL* delegate)
{
static_assert (_Fun<DEL>(), "Delegate must be function-like");
using Ret = typename _Fun<DEL>::Ret;
using Ret = _Fun<DEL>::Ret;
static_assert (_Fun<Ret>(), "Result from invoking delegate must also be function-like");
static_assert (has_Sig<Ret, SIG>(), "Result from delegate must expose target signature");

View file

@ -76,11 +76,11 @@ namespace lumiera {
const char * ON_BASIC_INIT ("ON_BASIC_INIT");
const char * ON_GLOBAL_INIT ("ON_GLOBAL_INIT");
const char * ON_GLOBAL_SHUTDOWN ("ON_GLOBAL_SHUTDOWN");
CStr ON_BASIC_INIT ("ON_BASIC_INIT");
CStr ON_GLOBAL_INIT ("ON_GLOBAL_INIT");
CStr ON_GLOBAL_SHUTDOWN ("ON_GLOBAL_SHUTDOWN");
const char * ON_EMERGENCY ("ON_EMERGENCY");
CStr ON_EMERGENCY ("ON_EMERGENCY");
} // namespace lumiera

View file

@ -184,7 +184,7 @@ namespace lib {
* discarding of node elements
*/
explicit
LinkedElements (typename ALO::CustomAllocator allo)
LinkedElements (ALO::CustomAllocator allo)
: ALO{allo}
, head_{nullptr}
{ }

View file

@ -114,7 +114,7 @@
{ \
\
template<class X> \
static Yes_t check(typename X::_TYPE_ *); \
static Yes_t check(X::_TYPE_ *); \
template<class> \
static No_t check(...); \
\
@ -183,30 +183,30 @@
* and return type. Yet a non-function member will not trigger this detector.
* @note this check will fail if there are overloads or similar ambiguity
*/
#define META_DETECT_FUNCTION_NAME(_FUN_NAME_) \
template<typename TY> \
class HasFunName_##_FUN_NAME_ \
{ \
template<typename SEL> \
struct Probe; \
template<class C, typename RET, typename...ARGS> \
struct Probe<RET (C::*) (ARGS...)> \
{ \
using Match = void; \
}; \
template<class C, typename RET, typename...ARGS> \
struct Probe<RET (C::*) (ARGS...) const> \
{ \
using Match = void; \
}; \
\
template<class X> \
static Yes_t check(typename Probe<decltype(&X::_FUN_NAME_)>::Match * ); \
template<class> \
static No_t check(...); \
\
public: \
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
#define META_DETECT_FUNCTION_NAME(_FUN_NAME_) \
template<typename TY> \
class HasFunName_##_FUN_NAME_ \
{ \
template<typename SEL> \
struct Probe; \
template<class C, typename RET, typename...ARGS> \
struct Probe<RET (C::*) (ARGS...)> \
{ \
using Match = void; \
}; \
template<class C, typename RET, typename...ARGS> \
struct Probe<RET (C::*) (ARGS...) const> \
{ \
using Match = void; \
}; \
\
template<class X> \
static Yes_t check(Probe<decltype(&X::_FUN_NAME_)>::Match * ); \
template<class> \
static No_t check(...); \
\
public: \
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
};
@ -216,22 +216,22 @@
* @remarks the presence of overloads is irrelevant, since we explicitly
* from an invocation to that function (within `decltype`)
*/
#define META_DETECT_FUNCTION_ARGLESS(_FUN_) \
template<typename TY> \
class HasArglessFun_##_FUN_ \
{ \
template<typename X, \
#define META_DETECT_FUNCTION_ARGLESS(_FUN_) \
template<typename TY> \
class HasArglessFun_##_FUN_ \
{ \
template<typename X, \
typename SEL = decltype(std::declval<X>()._FUN_())>\
struct Probe \
{ }; \
\
template<class X> \
static Yes_t check(Probe<X> * ); \
template<class> \
static No_t check(...); \
\
public: \
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
struct Probe \
{ }; \
\
template<class X> \
static Yes_t check(Probe<X> * ); \
template<class> \
static No_t check(...); \
\
public: \
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
};
@ -245,22 +245,22 @@
* type checks, the extension point is assumed to be supported.
* @warning beware of implicit type conversions
*/
#define META_DETECT_EXTENSION_POINT(_FUN_) \
template<typename TY> \
class HasExtensionPoint_##_FUN_ \
{ \
template<typename X, \
#define META_DETECT_EXTENSION_POINT(_FUN_) \
template<typename TY> \
class HasExtensionPoint_##_FUN_ \
{ \
template<typename X, \
typename SEL = decltype( _FUN_(std::declval<X>()))>\
struct Probe \
{ }; \
\
template<class X> \
static Yes_t check(Probe<X> * ); \
template<class> \
static No_t check(...); \
\
public: \
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
struct Probe \
{ }; \
\
template<class X> \
static Yes_t check(Probe<X> * ); \
template<class> \
static No_t check(...); \
\
public: \
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
};

View file

@ -96,7 +96,7 @@ namespace func{
template<typename X, typename TAIL, size_t i>
struct PlaceholderTuple<Node<X,TAIL>, i>
{
using TailPlaceholders = typename PlaceholderTuple<TAIL,i+1>::List;
using TailPlaceholders = PlaceholderTuple<TAIL,i+1>::List;
using List = Node<_Placeholder<i>, TailPlaceholders>;
};
@ -136,7 +136,7 @@ namespace func{
struct PartiallyInitTuple
{
template<size_t i>
using DestType = typename std::tuple_element_t<i, TAR>;
using DestType = std::tuple_element_t<i, TAR>;
/**
@ -230,17 +230,17 @@ namespace func{
* argument positions marked with `std::_Placeholder<N>` instances
* will remain _open_ to accept arguments on the resulting function.
*/
template<class FUN, class TUP, typename = enable_if_Tuple<TUP>>
template<class FUN, class TUP> requires(tuple_like<remove_reference_t<TUP>>)
auto
bindArgTuple (FUN&& fun, TUP&& tuple)
{
return std::apply ([functor = forward<FUN>(fun)]
(auto&&... args)
{
return std::bind (move(functor)
,forward<decltype(args)> (args) ...);
}
,std::forward<TUP> (tuple));
return lib::meta::apply ([functor = forward<FUN>(fun)]
(auto&&... args)
{
return std::bind (move(functor)
,forward<decltype(args)> (args) ...);
}
,std::forward<TUP> (tuple));
}
/**
@ -257,8 +257,8 @@ namespace func{
buildInvokableWrapper (FUN&& fun)
{
static_assert (is_Typelist<TYPES>::value);
using ArgTypes = typename TYPES::Seq;
using Builder = typename lib::meta::RebindVariadic<AdaptInvokable, ArgTypes>::Type;
using ArgTypes = TYPES::Seq;
using Builder = lib::meta::RebindVariadic<AdaptInvokable, ArgTypes>::Type;
return Builder::buildWrapper (forward<FUN> (fun));
}
@ -290,11 +290,11 @@ namespace func{
template<typename SIG, typename VAL>
class PApply
{
using Args = typename _Fun<SIG>::Args;
using Ret = typename _Fun<SIG>::Ret;
using ArgsList = typename Args::List;
using ValList = typename VAL::List;
using ValTypes = typename Types<ValList>::Seq; // reconstruct a type-seq from a type-list
using Args = _Fun<SIG>::Args;
using Ret = _Fun<SIG>::Ret;
using ArgsList = Args::List;
using ValList = VAL::List;
using ValTypes = Types<ValList>::Seq; // reconstruct a type-seq from a type-list
enum { ARG_CNT = count<ArgsList>()
, VAL_CNT = count<ValList>()
@ -303,34 +303,34 @@ namespace func{
// create list of the *remaining* arguments, after applying the ValList
using LeftReduced = typename Splice<ArgsList, ValList>::Back;
using RightReduced = typename Splice<ArgsList, ValList, ROFFSET>::Front;
using LeftReduced = Splice<ArgsList, ValList>::Back;
using RightReduced = Splice<ArgsList, ValList, ROFFSET>::Front;
using ArgsL = typename Types<LeftReduced>::Seq;
using ArgsR = typename Types<RightReduced>::Seq;
using ArgsL = Types<LeftReduced>::Seq;
using ArgsR = Types<RightReduced>::Seq;
// build a list, where each of the *remaining* arguments is replaced by a placeholder marker
using TrailingPlaceholders = typename func::PlaceholderTuple<LeftReduced>::List;
using LeadingPlaceholders = typename func::PlaceholderTuple<RightReduced>::List;
using TrailingPlaceholders = func::PlaceholderTuple<LeftReduced>::List;
using LeadingPlaceholders = func::PlaceholderTuple<RightReduced>::List;
// ... and splice these placeholders on top of the original argument type list,
// thus retaining the types to be closed, but setting a placeholder for each remaining argument
using LeftReplaced = typename Splice<ArgsList, TrailingPlaceholders, VAL_CNT>::List;
using RightReplaced = typename Splice<ArgsList, LeadingPlaceholders, 0 >::List;
using LeftReplaced = Splice<ArgsList, TrailingPlaceholders, VAL_CNT>::List;
using RightReplaced = Splice<ArgsList, LeadingPlaceholders, 0 >::List;
using LeftReplacedTypes = typename Types<LeftReplaced>::Seq;
using RightReplacedTypes = typename Types<RightReplaced>::Seq;
using LeftReplacedTypes = Types<LeftReplaced>::Seq;
using RightReplacedTypes = Types<RightReplaced>::Seq;
// create a "builder" helper, which accepts exactly the value tuple elements
// and puts them at the right location, while default-constructing the remaining
// (=placeholder)-arguments. Using this builder helper, we can finally set up
// the argument tuples (Left/RightReplacedArgs) used for the std::bind call
template<class SRC, class TAR, size_t i>
using IdxSelectorL = typename PartiallyInitTuple<SRC, TAR, 0>::template IndexMapper<i>;
using IdxSelectorL = PartiallyInitTuple<SRC, TAR, 0>::template IndexMapper<i>;
template<class SRC, class TAR, size_t i>
using IdxSelectorR = typename PartiallyInitTuple<SRC, TAR, ROFFSET>::template IndexMapper<i>;
using IdxSelectorR = PartiallyInitTuple<SRC, TAR, ROFFSET>::template IndexMapper<i>;
using BuildL = TupleConstructor<LeftReplacedTypes, IdxSelectorL>;
using BuildR = TupleConstructor<RightReplacedTypes, IdxSelectorR>;
@ -404,31 +404,31 @@ namespace func{
template<typename SIG, typename X, uint pos>
class BindToArgument
{
using Args = typename _Fun<SIG>::Args;
using Ret = typename _Fun<SIG>::Ret;
using ArgsList = typename Args::List;
using ValList = typename Types<X>::List;
using Args = _Fun<SIG>::Args;
using Ret = _Fun<SIG>::Ret;
using ArgsList = Args::List;
using ValList = Types<X>::List;
enum { ARG_CNT = count<ArgsList>() };
using RemainingFront = typename Splice<ArgsList, ValList, pos>::Front;
using RemainingBack = typename Splice<ArgsList, ValList, pos>::Back;
using PlaceholdersBefore = typename func::PlaceholderTuple<RemainingFront>::List;
using PlaceholdersBehind = typename func::PlaceholderTuple<RemainingBack,pos+1>::List;
using RemainingFront = Splice<ArgsList, ValList, pos>::Front;
using RemainingBack = Splice<ArgsList, ValList, pos>::Back;
using PlaceholdersBefore = func::PlaceholderTuple<RemainingFront>::List;
using PlaceholdersBehind = func::PlaceholderTuple<RemainingBack,pos+1>::List;
using PreparedArgsRaw = typename Append<typename Append<PlaceholdersBefore // arguments before the splice: passed-through
,ValList >::List // splice in the value tuple
,PlaceholdersBehind // arguments behind the splice: passed-through
>::List;
using PreparedArgs = Prefix<PreparedArgsRaw, ARG_CNT>;
using ReducedArgs = typename Append<RemainingFront, RemainingBack>::List;
using ReducedArgs = Append<RemainingFront, RemainingBack>::List;
using PreparedArgTypes = typename Types<PreparedArgs>::Seq;
using RemainingArgs = typename Types<ReducedArgs>::Seq;
using PreparedArgTypes = Types<PreparedArgs>::Seq;
using RemainingArgs = Types<ReducedArgs>::Seq;
template<class SRC, class TAR, size_t i>
using IdxSelector = typename PartiallyInitTuple<SRC, TAR, pos>::template IndexMapper<i>;
using IdxSelector = PartiallyInitTuple<SRC, TAR, pos>::template IndexMapper<i>;
using BuildPreparedArgs = TupleConstructor<PreparedArgTypes, IdxSelector>;
@ -461,10 +461,10 @@ namespace func{
template<typename FUN1, typename FUN2>
struct _Chain
{
using Ret = typename _Fun<FUN2>::Ret;
using Args = typename _Fun<FUN1>::Args;
using Ret = _Fun<FUN2>::Ret;
using Args = _Fun<FUN1>::Args;
using FunType = typename BuildFunType<Ret,Args>::Fun;
using FunType = BuildFunType<Ret,Args>::Fun;
static auto adaptedFunType() { return FunType{}; }

View file

@ -250,7 +250,7 @@ namespace meta{
/** abbreviation for referring to a function's return type */
template<typename FUN>
using _FunRet = typename _Fun<FUN>::Ret;
using _FunRet = _Fun<FUN>::Ret;
namespace {
template<typename FUN>
@ -259,14 +259,14 @@ namespace meta{
static_assert(_Fun<FUN>() , "something funktion-like required");
static_assert(_Fun<FUN>::ARITY == 1 , "function with exactly one argument required");
using Sig = typename _Fun<FUN>::Sig;
using Arg = typename _Fun<Sig>::Args::List::Head;
using Sig = _Fun<FUN>::Sig;
using Arg = _Fun<Sig>::Args::List::Head;
};
}
/** abbreviation for referring to a function's single Argument type */
template<typename FUN>
using _FunArg = typename _DetectSingleArgFunction<FUN>::Arg;
using _FunArg = _DetectSingleArgFunction<FUN>::Arg;

View file

@ -236,7 +236,7 @@ namespace meta {
* reference to an anonymous temporary.
*/
template<typename X>
typename Unwrap<X>::Type&
Unwrap<X>::Type&
unwrap (X const& wrapped)
{
return Unwrap<X>::extract(wrapped);
@ -258,7 +258,7 @@ namespace meta {
using TypePointee = remove_pointer_t<TypeReferred>;
using TypePlain = remove_cv_t<TypePointee>;
using Type = typename Unwrap<TypePlain>::Type;
using Type = Unwrap<TypePlain>::Type;
};
@ -509,7 +509,7 @@ namespace meta {
template<typename T>
class can_IterForEach
{
using Type = typename Strip<T>::Type;
using Type = Strip<T>::Type;
META_DETECT_NESTED(value_type);
META_DETECT_OPERATOR_DEREF();
@ -533,7 +533,7 @@ namespace meta {
template<typename T>
class is_StateCore
{
using Type = typename Strip<T>::Type;
using Type = Strip<T>::Type;
META_DETECT_FUNCTION_ARGLESS(checkPoint);
META_DETECT_FUNCTION_ARGLESS(iterNext);
@ -554,7 +554,7 @@ namespace meta {
template<typename T>
class can_STL_ForEach
{
using Type = typename Strip<T>::Type;
using Type = Strip<T>::Type;
struct is_iterable
{
@ -618,7 +618,7 @@ namespace meta {
template<typename T>
class can_STL_backIteration
{
using Type = typename Strip<T>::Type;
using Type = Strip<T>::Type;
struct is_backIterable
{

View file

@ -133,15 +133,15 @@ namespace meta{
static auto
wrapBuilder (CLO closureFun) ///< need to provide the remaining arguments as a tuple
{
using RemainingArgs = typename _Fun<CLO>::Args;
using RemainingParams = typename lib::meta::RebindVariadic<TUP, RemainingArgs>::Type;
using RemainingArgs = _Fun<CLO>::Args;
using RemainingParams = lib::meta::RebindVariadic<TUP, RemainingArgs>::Type;
struct Wrap
{
auto
operator() (RemainingParams remPar) const
{
return apply (unConst(this)->partialClosure_, remPar);
return lib::meta::apply (unConst(this)->partialClosure_, remPar);
};
CLO partialClosure_;
@ -186,13 +186,13 @@ namespace meta{
template<typename T, size_t N>
struct _Adapt
{
using NFold = typename Repeat<T,N>::Seq;
using Array = typename RebindVariadic<ArrayAdapt, NFold>::Type;
using NFold = Repeat<T,N>::Seq;
using Array = RebindVariadic<ArrayAdapt, NFold>::Type;
static_assert(N,"attempt to partially close empty array");
};
template<typename T, size_t N>
using _AdaptArray_t = typename _Adapt<T,N>::Array;
using _AdaptArray_t = _Adapt<T,N>::Array;
}
/** @note adding seamless conversion and compount-init */

View file

@ -18,6 +18,12 @@
** to the tuple type provided by the standard library, including traits and
** helpers to build tuple types from metaprogramming and to pretty-print tuples.
**
** Notably, a `concept tuple_like` is provided, which is satisfied for any type in compliance
** with the »tuple protocol«. Together with a [generic accessor][\ref lib::meta::getElm),
** this allows to handle all _tuple-like_ types uniformly.
** @note Due to an unfortunate limitation of the standard, we're forced to provide our own alternative
** implementation to replace `std::apply`, so that a function can be applied to any _tuple-like_
**
** Furthermore, a generic iteration construct is provided, to instantiate
** a generic Lambda for each element of a given tuple, which allows to write
** generic code »for each tuple element«.
@ -71,12 +77,87 @@ namespace meta {
struct is_Tuple<const std::tuple<TYPES...>>
: std::true_type
{ };
using std::remove_cv_t;
using std::is_reference_v;
using std::remove_reference_t;
/** @internal building-block: a type supporting the `tuple_size` metafunction */
template<class TUP>
using enable_if_Tuple = lib::meta::enable_if<lib::meta::is_Tuple<std::remove_reference_t<TUP>>>;
concept tuple_sized = requires
{
{ std::tuple_size<TUP>::value } -> std::convertible_to<size_t>;
};
/** @internal building-block: a type where elements can be accessed through a `get` friend function */
template<class TUP, std::size_t idx>
concept tuple_adl_accessible = requires(TUP tup)
{
typename std::tuple_element_t<idx, TUP>;
{ get<idx>(tup) } -> std::convertible_to<std::tuple_element_t<idx, TUP>&>;
};
/** @internal building-block: a type where elements can be accessed through a `get` member function */
template<class TUP, std::size_t idx>
concept tuple_mem_accessible = requires(TUP tup)
{
typename std::tuple_element_t<idx, TUP>;
{ tup.template get<idx>() } -> std::convertible_to<std::tuple_element_t<idx, TUP>&>;
};
template<class TUP, std::size_t idx>
concept tuple_element_accessible = tuple_mem_accessible<TUP,idx> or tuple_adl_accessible<TUP,idx>;
template<class TUP>
using disable_if_Tuple = lib::meta::disable_if<lib::meta::is_Tuple<std::remove_reference_t<TUP>>>;
concept tuple_accessible =
tuple_sized<TUP> and
WithIdxSeq<std::tuple_size_v<TUP>>::andAll([](auto idx)
{
return tuple_element_accessible<TUP,idx>;
});
/**
* Concept to mark any type compliant to the »tuple protocol«
*/
template<class TUP>
concept tuple_like = not is_reference_v<TUP>
and tuple_sized<remove_cv_t<TUP>>
and tuple_accessible<remove_cv_t<TUP>>;
/**
* Helper for abstracted / unified access to member elements of any _tuple-like_
* @remark preferably uses a `get<i>` member function, falling back to a
* free function `get`, which is found by ADL.
*/
template<std::size_t idx, class TUP>
requires(tuple_like<std::remove_reference_t<TUP>>)
decltype(auto)
getElm (TUP&& tup)
{
using Tup = std::remove_reference_t<TUP>;
static_assert (0 < std::tuple_size_v<Tup>);
if constexpr (tuple_mem_accessible<Tup,0>)
{
if constexpr (std::is_reference_v<TUP>)
return tup.template get<idx>();
else
{ // return value copy when tuple given as RValue
using Elm = std::tuple_element_t<idx, TUP>;
Elm elm(tup.template get<idx>());
return elm;
}
}
else
{ // ▽▽▽ ADL
using std::get;
return get<idx> (std::forward<TUP> (tup));
}
}
@ -86,22 +167,29 @@ namespace meta {
template<typename FUN, typename TUP, size_t...Idx>
constexpr decltype(auto)
__unpack_and_apply (FUN&& f, TUP&& tup, std::index_sequence<Idx...>)
{ // ▽▽▽ ADL
using std::get;
{
return std::invoke (std::forward<FUN> (f)
,get<Idx> (std::forward<TUP>(tup))...
,getElm<Idx> (std::forward<TUP>(tup))...
);
}
/** @internal invoke a metafunction with \a FUN and all element types from \a TUP */
/** @internal invoke a metafunction with \a FUN and all element types from the _tuple-like_ \a TUP */
template<template<typename...> class META, class FUN, class TUP>
struct _InvokeMetafunTup
{
using Tupl = std::decay_t<TUP>;
using Elms = typename ElmTypes<Tupl>::Seq;
using Args = typename Prepend<FUN, Elms>::Seq;
using Type = typename RebindVariadic<META, Args>::Type;
using Elms = ElmTypes<Tupl>::Seq;
using Args = Prepend<FUN, Elms>::Seq;
using Type = RebindVariadic<META, Args>::Type;
};
template<template<typename...> class META, class FUN, class TUP>
struct _InvokeMetafunTup<META, FUN, TUP&>
{
using Tupl = std::decay_t<TUP>;
using Elms = typename ElmTypes<Tupl>::template Apply<std::add_lvalue_reference_t>;
using Args = Prepend<FUN, Elms>::Seq;
using Type = RebindVariadic<META, Args>::Type;
};
template<class FUN, class TUP>
@ -116,7 +204,7 @@ namespace meta {
* @todo 6/2025 as a first step, this replicates the implementation from C++17;
* the second step would be to constrain this to a concept `tuple_like`
*/
template<class FUN, class TUP>
template<class FUN, class TUP> requires(tuple_like<remove_reference_t<TUP>>)
constexpr decltype(auto)
apply (FUN&& f, TUP&& tup) noexcept (can_nothrow_invoke_tup<FUN,TUP> )
{
@ -137,15 +225,15 @@ namespace meta {
* std::apply to unpack the tuple's contents into an argument pack and
* then employ a fold expression with the comma operator.
*/
template<class TUP, class FUN, typename = enable_if_Tuple<TUP>>
template<class TUP, class FUN> requires(tuple_like<remove_reference_t<TUP>>)
constexpr void
forEach (TUP&& tuple, FUN fun)
{
std::apply ([&fun](auto&&... elms)
{
(fun (std::forward<decltype(elms)> (elms)), ...);
}
,std::forward<TUP> (tuple));
lib::meta::apply ([&fun]<typename...ELMS>(ELMS&&... elms)
{
(fun (std::forward<ELMS>(elms)), ...);
}
,std::forward<TUP> (tuple));
}
/**
@ -162,20 +250,56 @@ namespace meta {
* Notably this differs from #forEach, where a fold-expression with comma-operator
* is used, which is guaranteed to evaluate from left to right.
*/
template<class TUP, class FUN, typename = enable_if_Tuple<TUP>>
template<class TUP, class FUN> requires(tuple_like<remove_reference_t<TUP>>)
constexpr auto
mapEach (TUP&& tuple, FUN fun)
{
return std::apply ([&fun](auto&&... elms)
{ //..construct the type explicitly (make_tuple would decay fun result types)
using Tuple = std::tuple<decltype(fun (std::forward<decltype(elms)> (elms))) ...>;
return Tuple (fun (std::forward<decltype(elms)> (elms)) ...);
}
,std::forward<TUP> (tuple));
return lib::meta::apply ([&fun]<typename...ELMS>(ELMS&&... elms)
{ //..construct the type explicitly (make_tuple would decay fun result types)
using Tuple = std::tuple<decltype(fun (std::forward<ELMS>(elms))) ...>;
return Tuple (fun (std::forward<ELMS>(elms)) ...);
}
,std::forward<TUP> (tuple));
}
/**
* Specialisation of variadic access for any tuple-like
* @see variadic-helper.hpp
*/
template<tuple_like TUP>
struct ElmTypes<TUP>
{
template<typename>
struct Extract;
template<size_t...idx>
struct Extract<std::index_sequence<idx...>>
{
using ElmTypes = Types<std::tuple_element_t<idx,TUP> ...>;
};
static constexpr size_t SIZ = std::tuple_size_v<TUP>;
using Idx = std::make_index_sequence<SIZ>;
using Seq = Extract<Idx>::ElmTypes;
using Tup = RebindVariadic<std::tuple, Seq>::Type;
template<template<class> class META>
using Apply = ElmTypes<Seq>::template Apply<META>;
template<template<typename...> class O>
using Rebind = RebindVariadic<O, Seq>::Type;
template<template<class> class PRED>
using AndAll = ElmTypes<Apply<PRED>>::template Rebind<std::__and_>;
template<template<class> class PRED>
using OrAll = ElmTypes<Apply<PRED>>::template Rebind<std::__or_>;
};
namespace { // rebinding helper to create std::tuple from a type sequence
@ -194,8 +318,8 @@ namespace meta {
template<class H, typename TAIL>
struct BuildTupleType<Node<H, TAIL>>
{
using Seq = typename Types<Node<H,TAIL>>::Seq;
using Type = typename BuildTupleType<Seq>::Type;
using Seq = Types<Node<H,TAIL>>::Seq;
using Type = BuildTupleType<Seq>::Type;
};
template<>
@ -215,7 +339,7 @@ namespace meta {
* over clever re-use of existing types.
*/
template<typename TYPES>
using Tuple = typename BuildTupleType<TYPES>::Type;
using Tuple = BuildTupleType<TYPES>::Type;
using std::tuple_size;
@ -227,14 +351,14 @@ namespace meta {
template<typename...TYPES>
struct RebindTupleTypes
{
using Seq = typename Types<TYPES...>::Seq;
using List = typename Seq::List;
using Seq = Types<TYPES...>::Seq;
using List = Seq::List;
};
template<typename...TYPES>
struct RebindTupleTypes<std::tuple<TYPES...>>
{
using Seq = typename Types<TYPES...>::Seq;
using List = typename Seq::List;
using Seq = Types<TYPES...>::Seq;
using List = Seq::List;
};
@ -272,7 +396,7 @@ namespace meta {
: Tuple<TYPES>
{
/** meta-sequence to drive instantiation of the ElmMapper */
using SequenceIterator = typename BuildIdxIter<TYPES>::Ascending;
using SequenceIterator = BuildIdxIter<TYPES>::Ascending;
template<size_t idx, class SRC>
static auto
@ -312,7 +436,7 @@ namespace meta {
template<class SRC, class TAR, size_t i>
using ExtractArg = typename ElementExtractor<SRC, TAR>::template Access<i>;
using ExtractArg = ElementExtractor<SRC, TAR>::template Access<i>;
/**
@ -365,10 +489,10 @@ namespace meta {
class BuildTupleAccessor
{
// prepare recursion...
using Head = typename Split<TYPES>::Head;
using Tail = typename Split<TYPES>::Tail;
using Head = Split<TYPES>::Head;
using Tail = Split<TYPES>::Tail;
using NextBuilder = BuildTupleAccessor<_X_, Tail,TUP, i+1>;
using NextAccessor = typename NextBuilder::Product;
using NextAccessor = NextBuilder::Product;
public:
/** type of the product created by this template.
@ -451,7 +575,7 @@ namespace meta {
dump (std::tuple<TYPES...> const& tuple)
{
using BuildAccessor = BuildTupleAccessor<TupleElementDisplayer, Types<TYPES...>>;
using Displayer = typename BuildAccessor::Product ;
using Displayer = BuildAccessor::Product ;
return static_cast<Displayer const&> (tuple)
.dump();

View file

@ -107,7 +107,7 @@ namespace meta {
>
{ };
using SupportedSourceTypes = typename Filter<DataValues::List, allow_Conversion>::List;
using SupportedSourceTypes = Filter<DataValues::List, allow_Conversion>::List;
@ -193,7 +193,7 @@ namespace meta {
struct ElementExtractor<lib::diff::Rec, std::tuple<TYPES...>>
{
template<size_t i>
using TargetType = typename Pick<Types<TYPES...>, i>::Type;
using TargetType = Pick<Types<TYPES...>, i>::Type;
template<size_t i>

View file

@ -74,7 +74,7 @@ namespace meta {
template<class TY, class TYPES, size_t i>
struct Pick<Node<TY,TYPES>, i>
{
using Type = typename Pick<TYPES, i-1>::Type;
using Type = Pick<TYPES, i-1>::Type;
};
@ -111,11 +111,11 @@ namespace meta {
template< class TY, class TYPES
, template<class> class _P_
>
struct Filter<Node<TY,TYPES>,_P_> { using List = typename CondNode< _P_<TY>::value
, TY
, typename Filter<TYPES,_P_>::List
>::Next
; };
struct Filter<Node<TY,TYPES>,_P_> { using List = CondNode< _P_<TY>::value
, TY
, typename Filter<TYPES,_P_>::List
>::Next
; };
/** append (concatenate) lists-of-types */
@ -157,11 +157,11 @@ namespace meta {
using List = Nil; };
template<class TY, class TYPES>
struct PickLast<Node<TY,TYPES>> { using Type = typename PickLast<TYPES>::Type;
using List = typename Append< TY
, typename PickLast<TYPES>::List
>::List
; };
struct PickLast<Node<TY,TYPES>> { using Type = PickLast<TYPES>::Type;
using List = Append< TY
, typename PickLast<TYPES>::List
>::List
; };
@ -203,11 +203,11 @@ namespace meta {
/** extract prefix of given length */
template<class LI, uint l>
using Prefix = typename Splice<LI, Nil, l>::Front;
using Prefix = Splice<LI, Nil, l>::Front;
/** extract suffix starting at given pos */
template<class LI, uint p>
using Suffix = typename Splice<LI, Nil, p>::Back;
using Suffix = Splice<LI, Nil, p>::Back;
@ -222,13 +222,13 @@ namespace meta {
template<class T, class TYPES>
struct Dissect<Node<T,TYPES>>
{
using List = Node<T,TYPES>; ///< the complete list
using Head = T; ///< first element
using First = Node<T,Nil>; ///< a list containing the first element
using Tail = TYPES; ///< remainder of the list starting with the second elm.
using Prefix = typename PickLast<List>::List; ///< all of the list, up to but excluding the last element
using End = typename PickLast<List>::Type; ///< the last element
using Last = Node<End,Nil>; ///< a list containing the last element
using List = Node<T,TYPES>; ///< the complete list
using Head = T; ///< first element
using First = Node<T,Nil>; ///< a list containing the first element
using Tail = TYPES; ///< remainder of the list starting with the second elm.
using Prefix = PickLast<List>::List; ///< all of the list, up to but excluding the last element
using End = PickLast<List>::Type; ///< the last element
using Last = Node<End,Nil>; ///< a list containing the last element
};
template<>
@ -276,7 +276,7 @@ namespace meta {
* sources, i.e. the Cartesian product.
*/
template<class TY1,class TY2>
struct Distribute { using List = typename PrefixAll<TY1,TY2>::List; };
struct Distribute { using List = PrefixAll<TY1,TY2>::List; };
template<class TY>
struct Distribute<Nil,TY> { using List = Nil; };
@ -284,10 +284,10 @@ namespace meta {
template< class TY, class TYPES
, class TAIL
>
struct Distribute<Node<TY,TYPES>,TAIL> { using List = typename Append< typename PrefixAll<TY,TAIL>::List
, typename Distribute<TYPES,TAIL>::List
>::List
; };
struct Distribute<Node<TY,TYPES>,TAIL> { using List = Append< typename PrefixAll<TY,TAIL>::List
, typename Distribute<TYPES,TAIL>::List
>::List
; };
@ -306,17 +306,17 @@ namespace meta {
*/
template< class X
, template<class> class _ENUM_>
struct Combine { using List = typename Distribute< typename _ENUM_<X>::List
, NilNode
>::List; };
struct Combine { using List = Distribute< typename _ENUM_<X>::List
, NilNode
>::List; };
template< template<class> class _ENUM_>
struct Combine<Nil, _ENUM_ > { using List = NilNode; };
template< class TY, class TYPES
, template<class> class _ENUM_>
struct Combine<Node<TY,TYPES>,_ENUM_> { using List = typename Distribute< typename _ENUM_<TY>::List
, typename Combine<TYPES,_ENUM_>::List
>::List; };
struct Combine<Node<TY,TYPES>,_ENUM_> { using List = Distribute< typename _ENUM_<TY>::List
, typename Combine<TYPES,_ENUM_>::List
>::List; };
/** enumeration generator for the Combine metafunction,
* yielding an "on" and "off" case; the latter is
@ -334,7 +334,7 @@ namespace meta {
template<class FLAGS>
struct CombineFlags
{
using List = typename Combine<FLAGS, FlagOnOff>::List;
using List = Combine<FLAGS, FlagOnOff>::List;
};

View file

@ -94,7 +94,7 @@ namespace meta {
struct Prepend<T, Types<TYPES...>>
{
using Seq = Types<T, TYPES...>;
using List = typename Types<T, TYPES...>::List;
using List = Types<T, TYPES...>::List;
};
@ -108,9 +108,9 @@ namespace meta {
struct Types< Node<H,T> >
{
using List = Node<H,T>;
using Seq = typename Prepend< H
, typename Types<T>::Seq
>::Seq;
using Seq = Prepend< H
, typename Types<T>::Seq
>::Seq;
};
template<>
struct Types<Nil>
@ -135,7 +135,7 @@ namespace meta {
template<typename T1, typename...TS>
struct Split<Types<T1,TS...> >
{
using List = typename Types<T1,TS...>::List;
using List = Types<T1,TS...>::List;
using Head = T1;
using First = Types<T1>;
@ -143,11 +143,11 @@ namespace meta {
// for finding the end we need the help of typelist-util.hpp
using PrefixList = typename PickLast<List>::List;
using TailList = typename Tail::List;
using PrefixList = PickLast<List>::List;
using TailList = Tail::List;
using Prefix = typename Types<PrefixList>::Seq;
using End = typename PickLast<List>::Type;
using Prefix = Types<PrefixList>::Seq;
using End = PickLast<List>::Type;
using Last = Types<End>;
};
@ -180,17 +180,17 @@ namespace meta {
template<class TYPES, uint i=1>
class Shifted
{
using Tail = typename Split<TYPES>::Tail;
using Tail = Split<TYPES>::Tail;
public:
using Type = typename Shifted<Tail,i-1>::Type;
using Head = typename Split<Type>::Head;
using Type = Shifted<Tail,i-1>::Type;
using Head = Split<Type>::Head;
};
template<class TYPES>
struct Shifted<TYPES,0>
{
using Type = TYPES;
using Head = typename Split<Type>::Head; ///< @warning may be Nil in case of an empty list
using Head = Split<Type>::Head; ///< @warning may be Nil in case of an empty list
};
@ -202,7 +202,7 @@ namespace meta {
template<typename...TYPES, size_t i>
struct Pick<Types<TYPES...>, i>
{
using Type = typename Shifted<Types<TYPES...>, i>::Head;
using Type = Shifted<Types<TYPES...>, i>::Head;
};
@ -214,8 +214,8 @@ namespace meta {
template<typename T, size_t N>
struct Repeat
{
using Rem = typename Repeat<T, N-1>::Seq;
using Seq = typename Prepend<T,Rem>::Seq;
using Rem = Repeat<T, N-1>::Seq;
using Seq = Prepend<T,Rem>::Seq;
};
template<typename T>

View file

@ -84,10 +84,10 @@ namespace meta {
* @see [std::enable_if](http://en.cppreference.com/w/cpp/types/enable_if)
*/
template <class Cond, class T = void>
using enable_if = typename enable_if_c<Cond::value, T>::type;
using enable_if = enable_if_c<Cond::value, T>::type;
template <class Cond, class T = void>
using disable_if = typename enable_if_c<not Cond::value, T>::type;
using disable_if = enable_if_c<not Cond::value, T>::type;
@ -114,9 +114,9 @@ namespace meta {
class _DetectNested_TypeResult
{
template<class ZZ>
static Yes_t check(typename ZZ::type *);
static Yes_t check(ZZ::type *);
template<class X>
static Yes_t check(typename X::Type *);
static Yes_t check(X::Type *);
template<class>
static No_t check(...);
@ -145,7 +145,7 @@ namespace meta {
}
/** helper to extract the first argument from a variadic arg pack, if any */
template<typename...XS>
using extractFirst_t = typename _ExtractFirst<XS...>::Type;
using extractFirst_t = _ExtractFirst<XS...>::Type;
@ -193,33 +193,6 @@ namespace meta {
namespace {
/**
* check for the necessary precondition, not sufficient.
* @remark Detecting the possibility of structured binding reliably will be possible with C++23.
* Even a partial implementation, covering only `std::tuple_element` is surprisingly
* complicated, due to the built-in limit checks. What do do with a `tuple<>`?
*/
template<class TUP, size_t siz =std::tuple_size<TUP>::value>
struct _Probe_TupleProtocol
{ };
}
template<class TUP>
using enable_if_TupleProtocol = std::void_t<_Probe_TupleProtocol<std::decay_t<TUP>>>;
/** Trait template to detect a »tuple-like« type,
* which can be used in structured bindings.
* @note we check only one precondition: the support for `std::tuple_size`
*/
template<class X, typename =void>
struct is_Structured
: std::false_type
{ };
template<class TUP>
struct is_Structured<TUP, enable_if_TupleProtocol<TUP>>
: std::true_type
{ };
/** Trait template for detecting a typelist type.
@ -231,7 +204,7 @@ namespace meta {
class is_Typelist
{
template<class X>
static Yes_t check(typename X::List *);
static Yes_t check(X::List *);
template<class>
static No_t check(...);
@ -519,7 +492,7 @@ namespace util {
inline std::string
showSmartPtr (SP const& smPtr, std::string label = "smP")
{
using TargetType = typename SP::element_type;
using TargetType = SP::element_type;
return smPtr? label+"("+showAdr(smPtr.get()) + ") ↗" + StringConv<TargetType>::invoke(*smPtr)
: BOTTOM_INDICATOR + " «" + typeStr(smPtr) + "»";

View file

@ -107,20 +107,20 @@ namespace meta {
template<typename TY, typename SEL =void>
struct ValueTypeBinding
{
using value_type = typename RefTraits<TY>::Value;
using reference = typename RefTraits<TY>::Reference;
using pointer = typename RefTraits<TY>::Pointer;
using value_type = RefTraits<TY>::Value;
using reference = RefTraits<TY>::Reference;
using pointer = RefTraits<TY>::Pointer;
};
/** specialisation for classes providing STL style type binding definitions */
template<typename TY>
struct ValueTypeBinding<TY, enable_if<use_ValueTypebindings<TY>> >
{
using _SrcType = typename RefTraits<TY>::Value;
using _SrcType = RefTraits<TY>::Value;
using value_type = typename _SrcType::value_type;
using reference = typename _SrcType::reference;
using pointer = typename _SrcType::pointer;
using value_type = _SrcType::value_type;
using reference = _SrcType::reference;
using pointer = _SrcType::pointer;
};
@ -159,9 +159,9 @@ namespace meta {
>;
using ResType = _ValRef;
using value_type = typename RefTraits<ResType>::Value;
using reference = typename RefTraits<ResType>::Reference;
using pointer = typename RefTraits<ResType>::Pointer;
using value_type = RefTraits<ResType>::Value;
using reference = RefTraits<ResType>::Reference;
using pointer = RefTraits<ResType>::Pointer;
};

View file

@ -70,20 +70,20 @@ namespace meta {
template<size_t n>
struct BuildIndexSeq
{
using Ascending = typename BuildIndexSeq<n-1>::Ascending::template AppendElm<n-1>;
using Descending = typename BuildIndexSeq<n-1>::Descending::template PrependElm<n-1>;
using Ascending = BuildIndexSeq<n-1>::Ascending::template AppendElm<n-1>;
using Descending = BuildIndexSeq<n-1>::Descending::template PrependElm<n-1>;
template<size_t d>
using OffsetBy = typename BuildIndexSeq<n-1>::template OffsetBy<d>::template AppendElm<n-1+d>;
using OffsetBy = BuildIndexSeq<n-1>::template OffsetBy<d>::template AppendElm<n-1+d>;
template<size_t x>
using FilledWith = typename BuildIndexSeq<n-1>::template FilledWith<x>::template AppendElm<x>;
using FilledWith = BuildIndexSeq<n-1>::template FilledWith<x>::template AppendElm<x>;
template<size_t c>
using First = typename BuildIndexSeq<std::min(c,n)>::Ascending;
using First = BuildIndexSeq<std::min(c,n)>::Ascending;
template<size_t c>
using After = typename BuildIndexSeq< (n>c)? n-c : 0>::template OffsetBy<c>;
using After = BuildIndexSeq< (n>c)? n-c : 0>::template OffsetBy<c>;
};
template<>
@ -118,20 +118,20 @@ namespace meta {
enum {SIZ = sizeof...(TYPES) };
using Builder = BuildIndexSeq<SIZ>;
using Ascending = typename Builder::Ascending;
using Descending = typename Builder::Descending;
using Ascending = Builder::Ascending;
using Descending = Builder::Descending;
template<size_t d>
using OffsetBy = typename Builder::template OffsetBy<d>;
using OffsetBy = Builder::template OffsetBy<d>;
template<size_t x>
using FilledWith = typename Builder::template FilledWith<x>;
using FilledWith = Builder::template FilledWith<x>;
template<size_t c>
using First = typename Builder::template First<c>;
using First = Builder::template First<c>;
template<size_t c>
using After = typename Builder::template After<c>;
using After = Builder::template After<c>;
};
/** build an index number sequence from a type sequence */
@ -193,47 +193,16 @@ namespace meta {
using Apply = Types<META<TYPES>...>;
template<template<typename...> class O>
using Rebind = typename lib::meta::RebindVariadic<O, Seq>::Type;
using Rebind = lib::meta::RebindVariadic<O, Seq>::Type;
template<template<class> class PRED>
using AndAll = typename ElmTypes<Apply<PRED>>::template Rebind<std::__and_>;
using AndAll = ElmTypes<Apply<PRED>>::template Rebind<std::__and_>;
template<template<class> class PRED>
using OrAll = typename ElmTypes<Apply<PRED>>::template Rebind<std::__or_>;
using OrAll = ElmTypes<Apply<PRED>>::template Rebind<std::__or_>;
};
/** partial specialisation to handle types
* supporting the C++ »tuple protocol«
*/
template<class TUP>
struct ElmTypes<TUP, enable_if_TupleProtocol<TUP>>
{
template<typename>
struct Extract;
template<size_t...idx>
struct Extract<std::index_sequence<idx...>>
{
using ElmTypes = Types<typename std::tuple_element<idx,TUP>::type ...>;
};
static constexpr size_t SIZ = std::tuple_size<TUP>::value;
using Idx = std::make_index_sequence<SIZ>;
using Seq = typename Extract<Idx>::ElmTypes;
using Tup = typename RebindVariadic<std::tuple, Seq>::Type;
template<template<class> class META>
using Apply = typename ElmTypes<Seq>::template Apply<META>;
template<template<typename...> class O>
using Rebind = typename RebindVariadic<O, Seq>::Type;
template<template<class> class PRED>
using AndAll = typename ElmTypes<Apply<PRED>>::template Rebind<std::__and_>;
template<template<class> class PRED>
using OrAll = typename ElmTypes<Apply<PRED>>::template Rebind<std::__or_>;
};
// Note: a further specialisation for any »tuple-like« is defined in tuple-helper.hpp
@ -244,23 +213,56 @@ namespace meta {
/** helper to invoke a functor, passing instances of std::integral_constant
* @tparam N size of the index-sequence to use for instantiation
* @remark the functor is given for...
* - to be invoked either (as void) for each index
* - or as a predicate, combining the results with AND / OR
*/
template<size_t N>
class WithIdxSeq
{
template<class FUN, size_t...idx>
static void
invoke (FUN&& fun, std::index_sequence<idx...>)
static constexpr void
invoke_forEach (FUN&& fun, std::index_sequence<idx...>)
{
(fun (std::integral_constant<size_t,idx>{}), ...);
}
template<class FUN, size_t...idx>
static constexpr bool
and_forEach (FUN&& fun, std::index_sequence<idx...>)
{
return (fun (std::integral_constant<size_t,idx>{}) and ...);
}
template<class FUN, size_t...idx>
static constexpr bool
or_forEach (FUN&& fun, std::index_sequence<idx...>)
{
return (fun (std::integral_constant<size_t,idx>{}) or ...);
}
using IdxSeq = std::make_index_sequence<N>;
public:
template<class FUN>
static void
static constexpr void
invoke (FUN&& fun)
{
invoke (std::forward<FUN>(fun), std::make_index_sequence<N>{});
invoke_forEach (std::forward<FUN>(fun), IdxSeq{});
}
template<class FUN>
static constexpr bool
andAll (FUN&& fun)
{
return and_forEach (std::forward<FUN>(fun), IdxSeq{});
}
template<class FUN>
static constexpr bool
orAny (FUN&& fun)
{
return or_forEach (std::forward<FUN>(fun), IdxSeq{});
}
};
@ -268,30 +270,31 @@ namespace meta {
* Invoke a function (or λ) with index numbers derived from some variadic count.
* Notably this construct can be used for compile-time iteration over a structure.
* Instances of `std::integral_constant` are passed in sequence to the functor.
* The _size_ of the index sequence is derived from the following sources
* The _size_ of the index sequence is derived using a \ref ElmTypes specialisation
* - if the type \a TTX is _tuple-like,_ then std::tuple_size<TTX> is used
* - otherwise, if the type is a loki-style type sequence or type list,
* the number of type nodes is used
* - otherwise, as fall-back the number of template parameters is used
* - otherwise, if the type is a _type sequence_ (`Types<T...>`), then
* the size of this meta sequence is used
* - otherwise, sequence-size 1 is used as fall-back
*/
template<class TTX, class FUN>
inline void
forEachIDX (FUN&& fun)
{
auto N = []{
if constexpr (is_Structured<TTX>())
return size_t(std::tuple_size<TTX>::value);
else
if constexpr (lib::meta::is_Typelist<TTX>::value)
return lib::meta::count<typename TTX::List>();
else
{ // Fallback: rebind template arguments into a type sequence
using Seq = typename RebindVariadic<Types, TTX>::Type;
return size_t(count<Seq>());
}
};
WithIdxSeq<N()>::invoke (std::forward<FUN> (fun));
WithIdxSeq<ElmTypes<TTX>::SIZ>::invoke (std::forward<FUN> (fun));
}
template<class TTX, class FUN>
inline bool
andAllIDX (FUN&& fun)
{
return WithIdxSeq<ElmTypes<TTX>::SIZ>::andAll (std::forward<FUN> (fun));
}
template<class TTX, class FUN>
inline bool
orAnyIDX (FUN&& fun)
{
return WithIdxSeq<ElmTypes<TTX>::SIZ>::orAny (std::forward<FUN> (fun));
}

View file

@ -34,13 +34,13 @@
** template<typename...CASES>
** struct MyModel
** {
** using SubSeq = typename _Vari<MyModel, CASES...>::Prefix;
** using SubSeq = _Vari<MyModel, CASES...>::Prefix;
**
** // adapt a predecessor sequence
** MyModel (SubSeq&& subModel);
**
**
** using Tuple = typename RebindVariadic<std::tuple, CASES...>::Type;
** using Tuple = RebindVariadic<std::tuple, CASES...>::Type;
** }
** \endcode
** @see param-weaving-pattern.hpp "usage example"
@ -138,15 +138,15 @@ namespace meta {
template<template<class...> class L, typename X, typename...XS>
struct _Vari<L, X,XS...>
{
using Penult = typename _Vari<L,XS...>::Penult;
using Ultima = typename _Vari<L,XS...>::Ultima;
using Penult = _Vari<L,XS...>::Penult;
using Ultima = _Vari<L,XS...>::Ultima;
using _Tail_Pre_ = typename _Vari<L,XS...>::Prefix;
using _Tail_Rev_ = typename _Vari<L,XS...>::Revers;
using _Tail_Pre_ = _Vari<L,XS...>::Prefix;
using _Tail_Rev_ = _Vari<L,XS...>::Revers;
using Remain = L<XS...>;
using Prefix = typename _Vari<L, X, _Tail_Pre_>::Prepend;
using Revers = typename _Vari<L, Ultima, _Tail_Rev_>::Prepend;
using Prefix = _Vari<L, X, _Tail_Pre_>::Prepend;
using Revers = _Vari<L, Ultima, _Tail_Rev_>::Prepend;
};
}} // namespace lib::meta

View file

@ -103,7 +103,7 @@ namespace lib {
template<typename RAW>
struct BuildRefcountPtr
{
using RawType = typename std::remove_pointer<RAW>::type;
using RawType = std::remove_pointer<RAW>::type;
using BareType = RawType *;
using ResultType = std::shared_ptr<RawType>;
@ -210,8 +210,8 @@ namespace lib {
struct FabConfig
{
using WrapFunctor = Wrapper<TY>;
using BareProduct = typename WrapFunctor::BareType;
using WrappedProduct = typename WrapFunctor::ResultType;
using BareProduct = WrapFunctor::BareType;
using WrappedProduct = WrapFunctor::ResultType;
typedef BareProduct SIG_Fab(void);
@ -228,8 +228,8 @@ namespace lib {
struct FabConfig<RET(ARGS...), Wrapper>
{
using WrapFunctor = Wrapper<RET>;
using BareProduct = typename WrapFunctor::BareType;
using WrappedProduct = typename WrapFunctor::ResultType;
using BareProduct = WrapFunctor::BareType;
using WrappedProduct = WrapFunctor::ResultType;
typedef BareProduct SIG_Fab(ARGS...);
@ -259,14 +259,14 @@ namespace lib {
: public FabConfig<SIG,Wrapper>::WrapFunctor
{
using _Conf = FabConfig<SIG,Wrapper>;
using SIG_Fab = typename _Conf::SIG_Fab;
using SIG_Fab = _Conf::SIG_Fab;
using _Fab = Fab<SIG_Fab,ID>;
_Fab funcTable_;
protected:
using Creator = typename _Fab::FactoryFunc;
using Creator = _Fab::FactoryFunc;
Creator&
selectProducer (ID const& id)
@ -276,7 +276,7 @@ namespace lib {
public:
using Product = typename _Conf::WrappedProduct;
using Product = _Conf::WrappedProduct;
/**
* Core operation of the factory:

View file

@ -200,7 +200,7 @@ namespace lib {
>
class InPlaceAnyHolder
{
using BaseP = typename AccessPolicy::Base *;
using BaseP = AccessPolicy::Base *;
/** Inner capsule managing the contained object (interface) */
struct Buffer

View file

@ -203,7 +203,7 @@ namespace util {
using PFun = FUN;
PFun parse;
using Result = typename _Fun<PFun>::Ret::Result;
using Result = _Fun<PFun>::Ret::Result;
Connex (FUN pFun)
: parse{pFun}
@ -281,7 +281,7 @@ namespace util {
inline auto
buildConnex (Syntax<PAR> const& anchor)
{
using Con = typename Syntax<PAR>::Connex;
using Con = Syntax<PAR>::Connex;
return Con{anchor};
}
@ -336,9 +336,9 @@ namespace util {
inline auto
adaptConnex (CON&& connex, BIND&& modelBinding)
{
using RX = typename CON::Result;
using RX = CON::Result;
using Arg = std::add_rvalue_reference_t<RX>;
using AdaptedRes = typename _ProbeFunReturn<Arg,BIND>::Ret;
using AdaptedRes = _ProbeFunReturn<Arg,BIND>::Ret;
return Connex{[origConnex = forward<CON>(connex)
,binding = forward<BIND>(modelBinding)
]
@ -357,7 +357,7 @@ namespace util {
inline auto
toStringConnex (CON&& connex, uint part)
{
using Result = typename CON::Result;
using Result = CON::Result;
return Connex([baseConnex = forward<CON>(connex)
,part
]
@ -442,9 +442,9 @@ namespace util {
/* === Builder functions to mark which side of the combinator to pick === */
using SubSeq = typename _Vari<AltModel, CASES...>::Prefix; ///< a nested sub-model to extend
using Penult = typename _Vari<AltModel, CASES...>::Penult; ///< plain value expected for left-branch
using Ultima = typename _Vari<AltModel, CASES...>::Ultima; ///< plain value expected for right-branch
using SubSeq = _Vari<AltModel, CASES...>::Prefix; ///< a nested sub-model to extend
using Penult = _Vari<AltModel, CASES...>::Penult; ///< plain value expected for left-branch
using Ultima = _Vari<AltModel, CASES...>::Ultima; ///< plain value expected for right-branch
static AltModel
mark_left (SubSeq&& leftCases)
@ -524,9 +524,9 @@ namespace util {
inline auto
sequenceConnex (C1&& connex1, C2&& connex2)
{
using R1 = typename decay_t<C1>::Result;
using R2 = typename decay_t<C2>::Result;
using ProductResult = typename _Join<SeqModel, R1, R2>::Result;
using R1 = decay_t<C1>::Result;
using R2 = decay_t<C2>::Result;
using ProductResult = _Join<SeqModel, R1, R2>::Result;
using ProductEval = Eval<ProductResult>;
return Connex{[conL = forward<C1>(connex1)
,conR = forward<C2>(connex2)
@ -558,9 +558,9 @@ namespace util {
inline auto
branchedConnex (C1&& connex1, C2&& connex2)
{
using R1 = typename decay_t<C1>::Result;
using R2 = typename decay_t<C2>::Result;
using SumResult = typename _Join<AltModel, R1, R2>::Result;
using R1 = decay_t<C1>::Result;
using R2 = decay_t<C2>::Result;
using SumResult = _Join<AltModel, R1, R2>::Result;
using SumEval = Eval<SumResult>;
return Connex{[conL = forward<C1>(connex1)
,conR = forward<C2>(connex2)
@ -595,7 +595,7 @@ namespace util {
,C1&& delimConnex
,C2&& bodyConnex)
{
using Res = typename decay_t<C2>::Result;
using Res = decay_t<C2>::Result;
using IterResult = IterModel<Res>;
using IterEval = Eval<IterResult>;
return Connex{[sep = forward<C1>(delimConnex)
@ -636,7 +636,7 @@ namespace util {
inline auto
optionalConnex (CNX&& connex)
{
using Res = typename decay_t<CNX>::Result;
using Res = decay_t<CNX>::Result;
using OptResult = optional<Res>;
using OptEval = Eval<OptResult>;
return Connex{[body = forward<CNX>(connex)
@ -661,7 +661,7 @@ namespace util {
,C3&& bodyConnex
,bool isOptional)
{
using Res = typename decay_t<C3>::Result;
using Res = decay_t<C3>::Result;
return Connex{[opening = forward<C1>(openingConnex)
,closing = forward<C2>(closingConnex)
,body = forward<C3>(bodyConnex)
@ -704,12 +704,12 @@ namespace util {
class Parser
: public CON
{
using PFun = typename CON::PFun;
using PFun = CON::PFun;
static_assert (_Fun<PFun>(), "Connex must define a parse-function");
public:
using Connex = CON;
using Result = typename CON::Result;
using Result = CON::Result;
static_assert (has_Sig<PFun, Eval<Result>(StrView)>()
,"Signature of the parse-function not suitable");
@ -785,8 +785,8 @@ namespace util {
PAR parse_;
public:
using Connex = typename PAR::Connex;
using Result = typename PAR::Result;
using Connex = PAR::Connex;
using Result = PAR::Result;
Syntax()
: parse_{Nil()}
@ -826,7 +826,7 @@ namespace util {
Syntax&
operator= (Syntax<PX> refSyntax)
{
using ConX = typename PX::Connex;
using ConX = PX::Connex;
ConX& refConnex = refSyntax;
parse_.parse = move(refConnex.parse);
return *this;

View file

@ -226,7 +226,6 @@ namespace lib {
{
static_assert (0 < chunk_size, "PathArray chunk_size must be nonempty");
using CcP = const char*;
using LiteralArray = std::array<Literal, chunk_size>;
LiteralArray elms_;
@ -245,8 +244,8 @@ namespace lib {
PathArray (IndexSeq<prefix...>
,IndexSeq<rest...>
,ARGS&& ...args)
: elms_{pickInit<prefix,CcP> (forward<ARGS>(args)...) ...}
, tail_{pickArg<rest> (forward<ARGS>(args)...) ...}
: elms_{pickInit<prefix, CStr> (forward<ARGS>(args)...) ...}
, tail_{pickArg<rest> (forward<ARGS>(args)...) ...}
{
this->normalise();
}
@ -260,8 +259,8 @@ namespace lib {
template<typename...ARGS>
struct Split
{
using Prefix = typename meta::BuildIndexSeq<chunk_size>::Ascending;
using Rest = typename meta::BuildIdxIter<ARGS...>::template After<chunk_size>;
using Prefix = meta::BuildIndexSeq<chunk_size>::Ascending;
using Rest = meta::BuildIdxIter<ARGS...>::template After<chunk_size>;
};
public:
@ -492,7 +491,7 @@ namespace lib {
normalise()
{
if (size() == 0) return;
const char* fill = Symbol::EMPTY;
CStr fill = Symbol::EMPTY;
Literal* end = elms_.end();
Literal* pos = elms_.begin();
@ -561,8 +560,8 @@ namespace lib {
{
if (l.size() != r.size()) return false;
typename PathArray<cl>::iterator lp = l.begin();
typename PathArray<cl>::iterator rp = r.begin();
auto lp = l.begin();
auto rp = r.begin();
while (lp and rp)
{
if (*lp != *rp) return false;

View file

@ -366,8 +366,8 @@ namespace lib {
{
private:
typedef polyvalue::Trait<CPY> _Traits;
typedef typename _Traits::CopyAPI _CopyHandlingAdapter;
typedef typename _Traits::Assignment _AssignmentPolicy; /////////////////TICKET #1197 : confusingly indirect decision logic
typedef _Traits::CopyAPI _CopyHandlingAdapter;
typedef _Traits::Assignment _AssignmentPolicy; /////////////////TICKET #1197 : confusingly indirect decision logic
enum{
siz = storage + _Traits::ADMIN_OVERHEAD
};

View file

@ -77,6 +77,7 @@ namespace lib {
return definition_;
}
auto operator<=> (QueryText const&) const =default;
bool
empty() const
@ -105,19 +106,6 @@ namespace lib {
private:
string normalise (string const& rawDefinition);
friend bool
operator== (QueryText const& q1, QueryText const& q2)
{
return q1.definition_ == q2.definition_;
}
friend bool
operator< (QueryText const& q1, QueryText const& q2)
{
return q1.definition_ < q2.definition_;
}
friend HashVal hash_value (QueryText const& entry);
};

View file

@ -175,11 +175,11 @@ namespace lib {
: public LazyInit<POL>
{
using Lazy = LazyInit<POL>;
using Disabled = typename Lazy::MarkDisabled;
using Disabled = Lazy::MarkDisabled;
using Sig = typename _Fun<POL>::Sig;
using Fun = function<Sig>;
using Tar = typename _Fun<POL>::Ret;
using Sig = _Fun<POL>::Sig;
using Fun = function<Sig>;
using Tar = _Fun<POL>::Ret;
Tar maxResult_{Tar::maxVal()}; ///< maximum result val actually to produce < max
Tar minResult_{Tar::minVal()}; ///< minimum result val actually to produce > min
@ -363,16 +363,16 @@ namespace lib {
using _Fun = lib::meta::_Fun<FUN>;
static_assert (_Fun(), "Need something function-like.");
using Sig = typename _Fun::Sig;
using Args = typename _Fun::Args;
using BaseIn = typename lib::meta::_Fun<POL>::Args;
using Sig = _Fun::Sig;
using Args = _Fun::Args;
using BaseIn = lib::meta::_Fun<POL>::Args;
if constexpr (std::is_same_v<Args, BaseIn>)
// function accepts same arguments as this RandomDraw
return forward<FUN> (fun); // pass-through directly
else
{// attempt to find a custom adaptor via Policy template
using Adaptor = typename POL::template Adaptor<Sig>;
using Adaptor = POL::template Adaptor<Sig>;
return Adaptor::build (forward<FUN> (fun));
}
}
@ -392,7 +392,7 @@ namespace lib {
{
static_assert (lib::meta::_Fun<FUN>(), "Need something function-like.");
using Res = typename lib::meta::_Fun<FUN>::Ret;
using Res = lib::meta::_Fun<FUN>::Ret;
using lib::meta::func::chained;
using lib::meta::_FunRet;

View file

@ -280,7 +280,7 @@ namespace lib {
public:
using GEN::GEN;
typename GEN::result_type
GEN::result_type
operator()()
{
if constexpr (GEN::max() < std::numeric_limits<typename GEN::result_type>::max())

View file

@ -30,6 +30,7 @@
** this kind of API design however is anything than trivial, given that
** any value can be thrown as exception in C++
** @see vault::ThreadJoinable usage example
** @see Result_test
*/
@ -40,7 +41,6 @@
#include "lib/error.hpp"
#include "lib/item-wrapper.hpp"
#include "lib/meta/util.hpp"
#include "lib/null-value.hpp"
#include <type_traits>
#include <exception>
@ -51,43 +51,13 @@
namespace lib {
namespace error = lumiera::error;
/**
* Helper to invoke an arbitrary callable in a failsafe way.
* @param capturedFailure *reference* to a std::exeption_ptr served by side-effect
* @param callable anything std::invoke can handle
* @return _if_ the invokable has a return type, the result is returned,
* _otherwise_ this is a void function
* @todo with C++20 the body of the implementation can be replaced by std::invoke_r //////////////////////TICKET #1245
*/
template<class FUN, typename...ARGS>
inline auto
failsafeInvoke (std::exception_ptr& capturedFailure
,FUN&& callable
,ARGS&& ...args) noexcept
{
using Res = std::invoke_result_t<FUN,ARGS...>;
try {
capturedFailure = nullptr;
if constexpr (std::is_void_v<Res>)
std::invoke (std::forward<FUN>(callable), std::forward<ARGS>(args)...);
else
return std::invoke (std::forward<FUN>(callable), std::forward<ARGS>(args)...);
}
catch(...)
{
capturedFailure = std::current_exception();
if constexpr (not std::is_void_v<Res>)
return lib::NullValue<Res>::get();
}
}
/**
* Representation of the result of some operation, _EITHER_ a value or a failure.
* It can be created for passing a result produced by the operation, or the failure
* to do so. The value can be retrieved by implicit or explicit conversion.
* @tparam RES the nominal result type to be captured from the function invocation.
* @throw error::State on any attempt to access the value in case of failure
* @warning this class has a lot of implicit conversions;
* care should be taken when defining functions
@ -123,9 +93,16 @@ namespace lib {
Result (FUN&& callable, ARGS&& ...args) noexcept
: failure_{}
{
failsafeInvoke (failure_
,std::forward<FUN> (callable)
,std::forward<ARGS>(args)...);
try {
static_assert (std::is_invocable_v<FUN,ARGS...>);
std::invoke (std::forward<FUN>(callable)
,std::forward<ARGS>(args)...
);
}
catch(...)
{
failure_ = std::current_exception();
}
}
explicit
@ -173,10 +150,19 @@ namespace lib {
template<class FUN, typename...ARGS, typename=lib::meta::enable_if<std::is_invocable<FUN,ARGS...>>>
Result (FUN&& callable, ARGS&& ...args) noexcept
: Result<void>{true}
, value_{failsafeInvoke (failure_
,std::forward<FUN> (callable)
,std::forward<ARGS>(args)...)}
{ }
, value_{}
{
try {
static_assert (std::is_invocable_r_v<RES,FUN,ARGS...>);
value_ = std::invoke_r<RES> (std::forward<FUN>(callable)
,std::forward<ARGS>(args)...
);
}
catch(...)
{
failure_ = std::current_exception();
}
}
// is or is not copyable depending on RES
@ -220,7 +206,7 @@ namespace lib {
/** deduction guide: find out about result value to capture from a generic callable. */
template<typename FUN, typename...ARGS>
Result (FUN&&, ARGS&&...) -> Result<std::invoke_result_t<FUN,ARGS...>>;
} // namespace lib

View file

@ -428,7 +428,7 @@ namespace lib {
{
public:
void
operator() (typename ScopedCollection<I,siz>::ElementHolder& storage)
operator() (ScopedCollection<I,siz>::ElementHolder& storage)
{
storage.template create<I>();
}
@ -440,7 +440,7 @@ namespace lib {
{
public:
void
operator() (typename ScopedCollection<I,siz>::ElementHolder& storage)
operator() (ScopedCollection<I,siz>::ElementHolder& storage)
{
storage.template create<TY>();
}
@ -461,7 +461,7 @@ namespace lib {
{
IT iter_;
using ElementType = typename meta::ValueTypeBinding<IT>::value_type;
using ElementType = meta::ValueTypeBinding<IT>::value_type;
public:
PullFrom (IT source)
@ -469,7 +469,7 @@ namespace lib {
{ }
void
operator() (typename ScopedCollection<I,siz>::ElementHolder& storage)
operator() (ScopedCollection<I,siz>::ElementHolder& storage)
{
storage.template create<ElementType> (*iter_);
++iter_;

View file

@ -68,13 +68,13 @@ namespace lib {
: util::MoveAssign
{
using _Vec = std::vector<T*>;
using VIter = typename _Vec::iterator;
using VIter = _Vec::iterator;
using RIter = RangeIter<VIter>;
using IterType = PtrDerefIter<RIter>;
using ConstIterType = typename IterType::ConstIterType;
using RcIter = typename IterType::WrappedConstIterType;
using ConstIterType = IterType::ConstIterType;
using RcIter = IterType::WrappedConstIterType;
_Vec vec_;

View file

@ -185,7 +185,7 @@ namespace lib {
using Bucket = ArrayBucket<I>;
template<typename X>
using XAlloT = typename AlloT::template rebind_traits<std::remove_cv_t<X>>;
using XAlloT = AlloT::template rebind_traits<std::remove_cv_t<X>>;
Allo& baseAllocator() { return *this; }
@ -193,7 +193,7 @@ namespace lib {
auto
adaptAllocator()
{
using XAllo = typename XAlloT<X>::allocator_type;
using XAllo = XAlloT<X>::allocator_type;
if constexpr (std::is_constructible_v<XAllo, Allo>)
return XAllo{baseAllocator()};
else
@ -401,7 +401,7 @@ namespace lib {
using Policy = POL<I,E>;
using Bucket = several::ArrayBucket<I>;
using Deleter = typename Bucket::Deleter;
using Deleter = Bucket::Deleter;
public:
SeveralBuilder() = default;
@ -477,7 +477,7 @@ namespace lib {
SeveralBuilder&&
appendAll (std::initializer_list<X> ili)
{
using Val = typename meta::Strip<X>::TypeReferred;
using Val = meta::Strip<X>::TypeReferred;
for (Val const& x : ili)
emplaceNewElm<Val> (x);
return move(*this);
@ -507,7 +507,7 @@ namespace lib {
SeveralBuilder&&
emplace (ARGS&& ...args)
{
using Val = typename meta::Strip<TY>::TypeReferred;
using Val = meta::Strip<TY>::TypeReferred;
emplaceNewElm<Val> (forward<ARGS> (args)...);
return move(*this);
}
@ -549,7 +549,7 @@ namespace lib {
void
emplaceCopy (IT& dataSrc)
{
using Val = typename IT::value_type;
using Val = IT::value_type;
emplaceNewElm<Val> (*dataSrc);
}
@ -557,7 +557,7 @@ namespace lib {
void
emplaceMove (IT& dataSrc)
{
using Val = typename IT::value_type;
using Val = IT::value_type;
emplaceNewElm<Val> (move (*dataSrc));
}
@ -737,9 +737,9 @@ namespace lib {
Deleter
selectDestructor()
{
using IVal = typename lib::meta::Strip<I>::TypeReferred;
using EVal = typename lib::meta::Strip<E>::TypeReferred;
using TVal = typename lib::meta::Strip<TY>::TypeReferred;
using IVal = lib::meta::Strip<I>::TypeReferred;
using EVal = lib::meta::Strip<E>::TypeReferred;
using TVal = lib::meta::Strip<TY>::TypeReferred;
typename Policy::Fac& factory(*this);
@ -783,8 +783,8 @@ namespace lib {
void
probeMoveCapability()
{
using TVal = typename lib::meta::Strip<TY>::TypeReferred;
using EVal = typename lib::meta::Strip<E>::TypeReferred;
using TVal = lib::meta::Strip<TY>::TypeReferred;
using EVal = lib::meta::Strip<E>::TypeReferred;
if (not (is_same_v<TVal,EVal> or is_trivially_copyable_v<TVal>))
lock_move = true;
@ -793,7 +793,7 @@ namespace lib {
bool
canWildMove()
{
using EVal = typename lib::meta::Strip<E>::TypeReferred;
using EVal = lib::meta::Strip<E>::TypeReferred;
return is_trivially_copyable_v<EVal> and not lock_move;
}

View file

@ -227,8 +227,8 @@ namespace lib {
friend auto begin (Several const& svl) { return svl.begin();}
friend auto end (Several const& svl) { return svl.end(); }
using value_type = typename meta::RefTraits<I>::Value;
using reference = typename meta::RefTraits<I>::Reference;
using value_type = meta::RefTraits<I>::Value;
using reference = meta::RefTraits<I>::Reference;
using const_reference = value_type const&;

View file

@ -456,7 +456,7 @@ namespace stat{
% csv.getParsedFieldCnt() % columnCnt % line};
}
using Value = typename std::remove_reference<decltype(col)>::type::ValueType;
using Value = std::remove_reference<decltype(col)>::type::ValueType;
col.get() = parseAs<Value>(*csv);
++csv;
});

View file

@ -2,7 +2,7 @@
Symbol(impl) - helpers for working with literal string IDs
Copyright (C)
2009, Hermann Vosseler <Ichthyostega@web.de>
2009,2017 Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
@ -12,15 +12,10 @@
* *****************************************************************/
/** @file symbol-impl.cpp
** Collection of helpers for working with the lib::Symbol.
**
** @todo currently as of 9/09 this is more of a placeholder.
** And maybe a location for collecting small bits of implementation,
** which could be usable later for real Symbol and Literal datatypes.
**
** lib::Symbol
** control::CommandRegistry for usage example of the hash function.
**
** Implementation functionality to support definition of lib::Symbol.
** @see lib::Symbol
** @see control::CommandRegistry for usage example of the hash function.
** @see symbol-table.hpp for the implementation of _interned strings_
*/
@ -45,7 +40,6 @@ namespace lib {
const size_t STRING_MAX_RELEVANT = LUMIERA_IDSTRING_MAX_RELEVANT;
namespace { // global symbol table
SymbolTable&
@ -54,12 +48,6 @@ namespace lib {
static SymbolTable theSymbolTable;
return theSymbolTable; // Meyer's Singleton
}
inline int
strNcmp (CStr a, CStr b, size_t len)
{
return a == b ? 0 : std::strncmp (a?a:"", b?b:"", len);
}
}
@ -87,14 +75,6 @@ namespace lib {
/** equality on Literal and Symbol values is defined
* based on the content, not the address. */
bool
Literal::operator== (CStr charPtr) const
{
return 0 == strNcmp (this->str_, charPtr, STRING_MAX_RELEVANT);
}
/** generate hash value based on the Literal's contents.
* This function is intended to be picked up by ADL, and should be usable
@ -107,7 +87,7 @@ namespace lib {
if (literal)
{
size_t cnt = 1;
const char *pos = literal;
CStr pos = literal;
for ( ; cnt <= STRING_MAX_RELEVANT and *pos ; ++cnt, ++pos )
hash_combine (hash, *pos);
}

View file

@ -2,7 +2,7 @@
SYMBOL.hpp - symbolic constant datatype
Copyright (C)
2008, Hermann Vosseler <Ichthyostega@web.de>
2008,2017 Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
@ -16,21 +16,22 @@
** Instead of working just with pointers, which could represent pretty much anything,
** it is prudent to express the meaning at interfaces and for variables and members explicitly.
**
** On concept level, while a string is just some sequence of characters and nothing can be said
** about mutability or lifetime, a Literal on the contrary is meant to be _static._ It is fixed
** and assumed to exist literally as is during the whole lifetime of the execution. The concept
** of a Symbol is related, yet slightly different: it is meant to be a distinguishable fixed,
** unique token. _Identical sequence_ of characters means we have exactly the _same Symbol._
** On conceptual level, while a **string** is just some sequence of characters and nothing can be
** said about its mutability or lifetime, a **Literal** is explicitly meant to be _static._ It is
** a fixed sequence of characters placed in a stable memory location and assumed to exist during
** the whole lifetime of the execution. The concept of a **Symbol** is slightly different: it is
** meant to be a distinguishable, fixed, unique token. An _Identical sequence_ of characters means
** we have _exactly the same Symbol_.
**
** These concepts can be fused by treating Symbol as a specialisation of Literal, additionally
** maintaining an automatically populated, static [symbol table](\ref symbol-table.hpp), and
** we close the circle by allowing Symbol instances to be created from strings at runtime.
**
** @remark this started on occasion 11/2008, just with a typedef to mark assumption on interfaces
** for rules based configuration in the Steam-Layer. Over time, conversions, comparison and
** hashcode implementation were added. It turned out that the most smooth integration in
** coding practice is achieved when allowing transparent conversion for Literal, but not
** for Symbol or std::string.
** @remark this abstraction was first used occasionally 11/2008, at that time just as a typedef
** to mark assumption on the new interfaces for rules based configuration in the Steam-Layer.
** Over time, conversions, comparison and hashcode implementation were added. It turned out
** that the most smooth integration in coding practice is achieved when allowing transparent
** conversion between Literal CStr, but not for Symbol or std::string.
** @todo 9/2017 consider this mostly as settled, but might require some finishing touches
** - maybe improve interoperation of Symbol and std::string
** - investigate performance of the automatic symbol table
@ -64,7 +65,7 @@ cStr (std::string const& rendered)
namespace lib {
/** inline string literal
/** Inline string literal.
* This is a _marker type_ to indicate that
* - the string was given literally
* - storage is _somewhere_, not managed by Literal,
@ -75,37 +76,38 @@ namespace lib {
*/
class Literal
{
CStr str_;
CStr str_;
public:
/** empty string by default */
Literal() noexcept;
Literal (const char* literal) noexcept
: str_(literal)
{ }
Literal (Literal const&) noexcept = default;
Literal& operator= (Literal const&) noexcept = default;
operator CStr() const { return str_; }
const char* c() const { return str_; }
bool
empty() const
{
return not str_ or 0 == std::strlen(str_);
}
bool operator== (CStr cString) const;
/** empty string by default */
constexpr Literal() noexcept;
constexpr Literal (CStr literal) noexcept
: str_(literal)
{ }
constexpr Literal (Literal const&) noexcept = default;
constexpr Literal& operator= (Literal const&) noexcept = default;
constexpr operator CStr() const { return str_; }
constexpr const char* c() const { return str_; }
constexpr bool
empty() const
{
return not str_ or 0 == std::strlen(str_);
}
constexpr bool operator== (CStr cString) const;
constexpr size_t length() const;
protected:
/** Assignment generally prohibited */
Literal& operator= (CStr newStr) noexcept
{
str_ = newStr;
return *this;
}
/** Assignment generally prohibited */
Literal& operator= (CStr newStr) noexcept
{
str_ = newStr;
return *this;
}
};
@ -140,31 +142,50 @@ namespace lib {
Symbol (Literal const& base, CStr ext)
: Symbol{base, std::string(ext)}
{ }
Symbol (Symbol const&) = default;
Symbol (Symbol &&) = default;
Symbol& operator= (Symbol const&) = default;
Symbol& operator= (Symbol &&) = default;
explicit operator bool() const { return not empty(); }
bool empty() const { return *this == BOTTOM.c() or *this == EMPTY.c(); }
size_t
length() const
{
return std::strlen(c());
}
Symbol (Symbol const&) = default;
Symbol (Symbol &&) = default;
Symbol& operator= (Symbol const&) = default;
Symbol& operator= (Symbol &&) = default;
explicit operator bool() const { return not empty(); }
bool empty() const { return *this == BOTTOM.c() or *this == EMPTY.c(); }
};
/** @note storage guaranteed to exist */
constexpr inline Literal::Literal() noexcept : str_(Symbol::EMPTY) { }
namespace{
constexpr inline int
strNcmp (CStr a, CStr b, size_t len)
{
return a == b ? 0 : std::strncmp (a?a:"", b?b:"", len);
}
}
/** safety guard: maximum number of chars to process.
* For comparisons, hash calculations etc., when dealing
* with raw char ptrs (typically literal values) */
extern const size_t STRING_MAX_RELEVANT;
/** @note storage guaranteed to exist */
inline Literal::Literal() noexcept : str_(Symbol::EMPTY) { }
/** equality on Literal and Symbol values is defined
* based on the content, not the address. */
constexpr inline bool
Literal::operator== (CStr charPtr) const
{
return 0 == strNcmp (this->str_, charPtr, STRING_MAX_RELEVANT);
}
constexpr inline size_t
Literal::length() const
{
return std::strlen(c());
}
/* ===== to be picked up by ADL ===== */
@ -175,35 +196,16 @@ namespace lib {
/* === equality comparisons === */
inline bool operator== (Literal const& s1, Literal const& s2) { return s1.operator== (s2.c()); }
inline bool operator== (Symbol const& s1, Symbol const& s2) { return s1.c() == s2.c(); } ///< @note comparison of symbol table entries
constexpr inline bool operator== (Literal const& s1, Literal const& s2) { return s1.operator== (s2.c()); }
constexpr inline bool operator== (Symbol const& s1, Symbol const& s2) { return s1.c() == s2.c(); } ///< @note comparison of symbol table entries
/* === mixed comparisons === */
inline bool operator== (CStr s1, Literal s2) { return s2.operator== (s1); }
inline bool operator== (Symbol s1, CStr s2) { return s1.operator== (s2); }
inline bool operator== (CStr s1, Symbol s2) { return s2.operator== (s1); }
inline bool operator== (Literal s1, Symbol s2) { return s1.operator== (s2.c()); }
inline bool operator== (Symbol s1, Literal s2) { return s2.operator== (s1.c()); }
inline bool operator== (Literal s1, std::string s2) { return s1.operator== (s2.c_str()); }
inline bool operator== (std::string s1, Literal s2) { return s2.operator== (s1.c_str()); }
inline bool operator== (Symbol s1, std::string s2) { return s1.operator== (s2.c_str()); }
inline bool operator== (std::string s1, Symbol s2) { return s2.operator== (s1.c_str()); }
/* === negations === */
inline bool operator!= (Literal const& s1, Literal const& s2) { return not s1.operator== (s2.c()); }
inline bool operator!= (Symbol const& s1, Symbol const& s2) { return not (s1.c() == s2.c()); }
inline bool operator!= (Literal s1, CStr s2) { return not s1.operator== (s2); }
inline bool operator!= (CStr s1, Literal s2) { return not s2.operator== (s1); }
inline bool operator!= (Symbol s1, CStr s2) { return not s1.operator== (s2); }
inline bool operator!= (CStr s1, Symbol s2) { return not s2.operator== (s1); }
inline bool operator!= (Literal s1, Symbol s2) { return not s1.operator== (s2.c()); }
inline bool operator!= (Symbol s1, Literal s2) { return not s2.operator== (s1.c()); }
inline bool operator!= (Literal s1, std::string s2) { return not s1.operator== (s2.c_str()); }
inline bool operator!= (std::string s1, Literal s2) { return not s2.operator== (s1.c_str()); }
inline bool operator!= (Symbol s1, std::string s2) { return not s1.operator== (s2.c_str()); }
inline bool operator!= (std::string s1, Symbol s2) { return not s2.operator== (s1.c_str()); }
constexpr inline bool operator== (CStr s1, Literal s2) { return s2.operator== (s1); }
constexpr inline bool operator== (Symbol s1, CStr s2) { return s1.operator== (s2); }
constexpr inline bool operator== (Literal s1, Symbol s2) { return s1.operator== (s2.c()); }
constexpr inline bool operator== (Literal s1, std::string const& s2) { return s1.operator== (s2.c_str()); }
constexpr inline bool operator== (Symbol s1, std::string const& s2) { return s1.operator== (s2.c_str()); }

View file

@ -55,8 +55,8 @@ namespace lib {
class ClassLock
: public Sync<CONF>::Lock
{
using Lock = typename Sync<CONF>::Lock;
using Monitor = typename sync::Monitor<CONF>;
using Lock = Sync<CONF>::Lock;
using Monitor = sync::Monitor<CONF>;
struct PerClassMonitor : Monitor {};

View file

@ -588,7 +588,7 @@ namespace test{
}
EventMatch&
EventMatch::on (const char* targetID)
EventMatch::on (CStr targetID)
{
refineSerach (solution_, matchAttribute("this",targetID));
evaluateQuery ("match-this(\""+string(targetID)+"\")");
@ -663,7 +663,7 @@ namespace test{
}
EventLog&
EventLog::clear (const char* alteredLogID)
EventLog::clear (CStr alteredLogID)
{
return clear (string{alteredLogID});
}
@ -700,7 +700,7 @@ namespace test{
}
EventLog&
EventLog::call (const char* target, const char* function, ArgSeq&& args)
EventLog::call (CStr target, CStr function, ArgSeq&& args)
{
return call (string(target), string(function), std::forward<ArgSeq>(args));
}

View file

@ -238,7 +238,7 @@ namespace test{
EventMatch& attrib (string key, string valueMatch);
EventMatch& id (string classifier);
EventMatch& on (string targetID);
EventMatch& on (const char* targetID);
EventMatch& on (CStr targetID);
template<typename X>
EventMatch& on (const X *const targetObj)
@ -298,7 +298,7 @@ namespace test{
EventLog (string logID);
explicit
EventLog (const char* logID)
EventLog (CStr logID)
: EventLog(string(logID))
{ }
@ -331,7 +331,7 @@ namespace test{
/** purge log contents while retaining just the original Header-ID */
EventLog& clear();
EventLog& clear (string alteredLogID);
EventLog& clear (const char* alteredLogID);
EventLog& clear (CStr alteredLogID);
template<class X>
EventLog&
@ -372,7 +372,7 @@ namespace test{
/** Log a function call with a sequence of stringified arguments */
EventLog& call (string target, string function, ArgSeq&& args);
EventLog& call (const char* target, const char* function, ArgSeq&& args);
EventLog& call (CStr target, CStr function, ArgSeq&& args);
/** Log a function call with arbitrary arguments */
template<typename...ARGS>
@ -392,7 +392,7 @@ namespace test{
template<typename...ARGS>
EventLog&
call (const char* target, string function, ARGS const& ...args)
call (CStr target, string function, ARGS const& ...args)
{
return call (string(target), function, args...);
}

View file

@ -151,7 +151,7 @@ namespace microbenchmark {
static_assert (lib::meta::_Fun<FUN>(), "Need something function-like.");
static_assert (lib::meta::_Fun<FUN>::ARITY <=1, "Function with zero or one argument required.");
using Sig = typename lib::meta::_Fun<FUN>::Sig;
using Sig = lib::meta::_Fun<FUN>::Sig;
return Adaptor<Sig>::wrap (std::forward<FUN> (fun));
}

View file

@ -105,7 +105,7 @@ namespace test{
*/
template<typename T>
inline string
showSizeof (T const* obj =0, const char* name =0)
showSizeof (T const* obj =0, CStr name =0)
{
return showSizeof (obj? sizeof(*obj) : sizeof(T),
name? name : util::typeStr(obj));
@ -114,14 +114,14 @@ namespace test{
template<typename T>
inline meta::disable_if<std::is_pointer<T>,
string > // note:: force invocations with pointer to the first overload
showSizeof (T const& obj, const char* name=0)
showSizeof (T const& obj, CStr name =nullptr)
{
return showSizeof (&obj, name);
}
template<typename T>
inline string
showSizeof (const char* name)
showSizeof (CStr name)
{
return showSizeof<T> (nullptr, name);
}
@ -257,7 +257,7 @@ namespace test{
showType()
{
using Case = TypeDiagnostics<X>;
using Type = typename Case::Type;
using Type = Case::Type;
return Case::prefix
+ meta::humanReadableTypeID (typeid(Type).name())
@ -375,7 +375,7 @@ namespace test{
* \endcode
*/
inline lib::test::ExpectString
operator""_expect (const char* lit, size_t siz)
operator""_expect (CStr lit, size_t siz)
{
return lib::test::ExpectString{lit, siz};
}

View file

@ -372,10 +372,10 @@ namespace lib {
class InstanceCore
{
using ActionIter = IndexIter<const ActionSeq>;
using DataCtxIter = typename SRC::Iter;
using DataCtxIter = SRC::Iter;
using NestedCtx = std::pair<DataCtxIter, SRC>;
using CtxStack = std::stack<NestedCtx, std::vector<NestedCtx>>;
using Value = typename SRC::Value;
using Value = SRC::Value;
SRC dataSrc_;
ActionIter actionIter_;
@ -826,7 +826,7 @@ namespace lib {
/** Instantiate next Action token and expose its rendering */
template<class SRC>
inline typename SRC::Value
inline SRC::Value
TextTemplate::InstanceCore<SRC>::instantiateNext()
{
return actionIter_? actionIter_->instantiate(*this)
@ -840,7 +840,7 @@ namespace lib {
* @return the rendering produced by the selected next Action token
*/
template<class SRC>
inline typename SRC::Value
inline SRC::Value
TextTemplate::InstanceCore<SRC>::reInstatiate (Idx nextCode)
{
if (nextCode == Idx(-1))
@ -852,7 +852,7 @@ namespace lib {
/** retrieve a data value from the data source for the indiated key */
template<class SRC>
inline typename SRC::Value
inline SRC::Value
TextTemplate::InstanceCore<SRC>::getContent (string key)
{
static Value nil{};

View file

@ -523,13 +523,13 @@ namespace lib {
static_assert(1 == _Fun<FUN>::ARITY);
static_assert(1 >= _Fun<HOOK>::ARITY);
// argument type expected by the hooks down in the policy class
using Arg = typename _Fun<FUN>::Args::List::Head;
using Arg = _Fun<FUN>::Args::List::Head;
// distinguish if user provided functor takes zero or one argument
if constexpr (0 == _Fun<HOOK>::ARITY)
return [hook = forward<HOOK>(hook)](Arg){ hook(); };
else
{ // instance type expected by the user-provided hook
using Target = typename _Fun<HOOK>::Args::List::Head;
using Target = _Fun<HOOK>::Args::List::Head;
return [hook = forward<HOOK>(hook)]
(Arg& threadWrapper)
{ // build a two-step cast path from the low-level wrapper to user type
@ -764,7 +764,7 @@ namespace lib {
inline void
launchDetached (string const& threadID, INVO&& ...args)
{
using Launch = typename TAR::Launch;
using Launch = TAR::Launch;
launchDetached<TAR> (Launch{forward<INVO> (args)...}
.threadID (threadID));
}
@ -774,7 +774,7 @@ namespace lib {
inline void
launchDetached (string const& threadID, void (TAR::*memFun) (ARGS...), ARGS ...args)
{
using Launch = typename TAR::Launch;
using Launch = TAR::Launch;
launchDetached<TAR> (Launch{std::move (memFun)
,lib::meta::InstancePlaceholder<TAR>{}
,forward<ARGS> (args)...

View file

@ -151,7 +151,7 @@ namespace mutation {
TI
operator() (TI const& changedVal) const
{
typedef typename ListenerList::const_iterator Iter;
using Iter = ListenerList::const_iterator;
Iter p = listeners_.begin();
Iter e = listeners_.end();

View file

@ -60,7 +60,6 @@
#include "lib/symbol.hpp"
#include "lib/util.hpp"
#include <boost/operators.hpp>
#include <boost/lexical_cast.hpp>
#include <functional>
#include <string>
@ -215,7 +214,6 @@ namespace time {
, class FMT = digxel::Formatter<NUM>
>
class Digxel
: public boost::totally_ordered<Digxel<NUM,FMT>>
{
mutable
FMT buffer_;
@ -297,9 +295,9 @@ namespace time {
NUM operator++ (int) { NUM p(value_); *this =p+1; return p;}
NUM operator-- (int) { NUM p(value_); *this =p-1; return p;}
//---Supporting-totally_ordered---------
bool operator< (Digxel const& o) const { return value_ < NUM(o); }
bool operator== (Digxel const& o) const { return value_ == NUM(o); }
//---Supporting-total-ordering----------
auto operator<=>(Digxel const& o) const { return value_ <=> NUM(o); }
bool operator== (Digxel const& o) const { return value_ == NUM(o); }
};

View file

@ -217,7 +217,7 @@ namespace time {
static Supported
formats()
{
typedef typename TY::List SupportedFormats;
using SupportedFormats = TY::List;
return Supported().define(SupportedFormats());
}

View file

@ -62,7 +62,6 @@
#include "lib/time/timecode.hpp"
#include "lib/symbol.hpp"
//#include <boost/operators.hpp>
#include <string>
@ -102,7 +101,7 @@ namespace time {
bool supports() const; ///< does our implicit time grid support building that timecode format?
template<class FMT>
typename format::Traits<FMT>::TimeCode
format::Traits<FMT>::TimeCode
formatAs() const; ///< create new time code instance, then #castInto
template<class TC>
@ -134,10 +133,10 @@ namespace time {
template<class FMT>
inline typename format::Traits<FMT>::TimeCode
inline format::Traits<FMT>::TimeCode
QuTime::formatAs() const
{
using TC = typename format::Traits<FMT>::TimeCode;
using TC = format::Traits<FMT>::TimeCode;
return TC(*this);
}
@ -155,7 +154,7 @@ namespace time {
inline void
QuTime::castInto (TC& timecode) const
{
using Format = typename TC::Format;
using Format = TC::Format;
REQUIRE (supports<Format>());
Format::rebuild (timecode, *quantiser_, TimeValue(*this));

View file

@ -99,6 +99,7 @@
#include <boost/operators.hpp>
#include <boost/rational.hpp>
#include <compare>
#include <cstdlib>
#include <string>
@ -139,8 +140,6 @@ namespace time {
* @see TimeVar when full arithmetics are required
*/
class TimeValue
: boost::totally_ordered<TimeValue,
boost::totally_ordered<TimeValue, raw_time_64>>
{
protected:
/** the raw (internal) time value
@ -196,12 +195,12 @@ namespace time {
/** @return is in-domain, not a boundary value */
bool isRegular() const;
// Supporting totally_ordered
friend bool operator< (TimeValue const& t1, TimeValue const& t2) { return t1.t_ < t2.t_; }
friend bool operator< (TimeValue const& t1, raw_time_64 t2) { return t1.t_ < t2 ; }
friend bool operator> (TimeValue const& t1, raw_time_64 t2) { return t1.t_ > t2 ; }
friend bool operator== (TimeValue const& t1, TimeValue const& t2) { return t1.t_ == t2.t_; }
friend bool operator== (TimeValue const& t1, raw_time_64 t2) { return t1.t_ == t2 ; }
// Supporting strong total ordering
std::strong_ordering operator<=> (TimeValue const&) const =default;
bool operator== (TimeValue const&) const =default;
std::strong_ordering operator<=> (raw_time_64 tt) const { return t_ <=> tt; }
bool operator== (raw_time_64 tt) const { return t_ == tt; }
};
@ -582,7 +581,6 @@ namespace time {
*/
class TimeSpan
: public Time
, boost::totally_ordered<TimeSpan>
{
Duration dur_;
@ -651,10 +649,15 @@ namespace time {
/** @internal diagnostics */
explicit operator std::string() const;
/// Supporting extended total order, based on start and interval length
friend bool operator== (TimeSpan const& t1, TimeSpan const& t2) { return t1.t_==t2.t_ && t1.dur_==t2.dur_; }
friend bool operator< (TimeSpan const& t1, TimeSpan const& t2) { return t1.t_< t2.t_ ||
(t1.t_==t2.t_ && t1.dur_< t2.dur_);}
/// Supporting extended strong total ordering, based on start and interval length
std::strong_ordering
operator<=> (TimeSpan const& ts) const
{
auto ord{ t_ <=> ts.t_ };
return ord != 0? ord
: dur_ <=> ts.dur_;
}
bool operator== (TimeSpan const& ts) const =default;
};

View file

@ -236,7 +236,7 @@ namespace lib {
}
friend string
operator+ (const char* prefix, FamilyMember id)
operator+ (CStr prefix, FamilyMember id)
{
return string(prefix)+id;
}

View file

@ -54,7 +54,7 @@ namespace util {
template<typename T>
struct treat_as_STL_Container
{
typedef typename lib::meta::Unwrap<T>::Type TaT;
typedef lib::meta::Unwrap<T>::Type TaT;
enum{ value = lib::meta::can_STL_ForEach<TaT>::value
&&!lib::meta::can_IterForEach<T>::value
@ -71,7 +71,7 @@ namespace util {
template<typename T>
struct can_direct_access_Last
{
typedef typename lib::meta::Unwrap<T>::Type TaT;
typedef lib::meta::Unwrap<T>::Type TaT;
enum{ value = lib::meta::can_STL_backIteration<TaT>::value
};
@ -159,7 +159,7 @@ namespace util {
inline auto
max (IT&& elms)
{
using Val = typename std::remove_reference_t<IT>::value_type;
using Val = std::remove_reference_t<IT>::value_type;
Val res = std::numeric_limits<Val>::min();
for (auto const& elm : std::forward<IT> (elms))
if (elm > res)
@ -171,7 +171,7 @@ namespace util {
inline auto
max (CON const& elms)
{
using Val = typename std::remove_reference_t<CON>::value_type;
using Val = std::remove_reference_t<CON>::value_type;
Val res = std::numeric_limits<Val>::min();
for (auto const& elm : elms)
if (elm > res)
@ -184,7 +184,7 @@ namespace util {
inline auto
min (IT&& elms)
{
using Val = typename std::remove_reference_t<IT>::value_type;
using Val = std::remove_reference_t<IT>::value_type;
Val res = std::numeric_limits<Val>::max();
for (auto const& elm : std::forward<IT> (elms))
if (elm < res)
@ -196,7 +196,7 @@ namespace util {
inline auto
min (CON const& elms)
{
using Val = typename std::remove_reference_t<CON>::value_type;
using Val = std::remove_reference_t<CON>::value_type;
Val res = std::numeric_limits<Val>::max();
for (auto const& elm : elms)
if (elm < res)

View file

@ -46,14 +46,14 @@ namespace std {// forward declarations to avoid pervasive includes
}
const char* cStr (std::string const&);
using CStr = const char*;
CStr cStr (std::string const&);
namespace util {
using std::string;
using CStr = const char*;
template <class NUM>
@ -271,7 +271,7 @@ namespace util {
/** fetch value from a Map, or return a default if not found */
template <typename MAP>
inline typename MAP::mapped_type
inline MAP::mapped_type
getValue_or_default (MAP& map, typename MAP::key_type const& key
, typename MAP::mapped_type defaultVal)
{
@ -288,7 +288,7 @@ namespace util {
* @see lib::NullValue
*/
template <typename MAP>
inline typename MAP::mapped_type const &
inline MAP::mapped_type const &
access_or_default (MAP& map, typename MAP::key_type const& key
, typename MAP::mapped_type const& refDefault)
{
@ -302,7 +302,7 @@ namespace util {
/** shortcut for removing all copies of an Element
* in any sequential collection */
template <typename SEQ>
inline typename SEQ::iterator
inline SEQ::iterator
removeall (SEQ& coll, typename SEQ::value_type const& val)
{
typename SEQ::iterator collEnd = coll.end();
@ -318,7 +318,7 @@ namespace util {
template<class SET, typename FUN>
bool remove_if (SET& set, FUN test)
{
typedef typename SET::iterator Itor;
using Itor = SET::iterator;
bool found = false;
Itor end = set.end();
Itor begin = set.begin();

View file

@ -221,9 +221,9 @@ namespace lib {
};
template<typename RET>
using VisitorFunc = typename variant::VFunc<RET>::template VisitorInterface<TYPES>;
using VisitorFunc = variant::VFunc<RET>::template VisitorInterface<TYPES>;
template<typename RET>
using VisitorConstFunc = typename variant::VFunc<RET>::template VisitorInterface<meta::ConstAll<typename TYPES::List>>;
using VisitorConstFunc = variant::VFunc<RET>::template VisitorInterface<meta::ConstAll<typename TYPES::List>>;
/**
* to be implemented by the client for visitation
@ -443,7 +443,7 @@ namespace lib {
Variant()
{
using DefaultType = typename TYPES::List::Head;
using DefaultType = TYPES::List::Head;
new(storage_) Buff<DefaultType> (DefaultType());
}
@ -453,7 +453,7 @@ namespace lib {
{
static_assert (variant::CanBuildFrom<X, TYPES>(), "No type in Typelist can be built from the given argument");
using StorageType = typename variant::CanBuildFrom<X, TYPES>::Type;
using StorageType = variant::CanBuildFrom<X, TYPES>::Type;
new(storage_) Buff<StorageType> (forward<X>(x));
}
@ -477,7 +477,7 @@ namespace lib {
Variant&
operator= (X x)
{
using RawType = typename std::remove_reference<X>::type;
using RawType = std::remove_reference<X>::type;
static_assert (meta::isInList<RawType, typename TYPES::List>(),
"Type error: the given variant could never hold the required type");
static_assert (std::is_copy_assignable<RawType>::value, "target type does not support assignment");

Some files were not shown because too many files have changed in this diff Show more