Welcome to bibi’s documentation!¶
bibi is a small header-only library which tries to implement the C++ Standard Library concepts using the Concepts Lite TS Syntax. In contrary to already existing libraries like origin, cmcstl2 or range-v3 its goal is to implement the concepts currently defined in the standard, therefore making it easy to introduce concepts to an existing codebase.
Quick Example¶
#include <bibi/Core.h>
#include <bibi/Algorithm.h>
#include <iostream>
#include <vector>
using namespace bibi;
auto negate(Signed s) {
return -s;
}
template<typename T>
concept bool SignedArithmetic = Arithmetic<T> && Signed<T>;
template<SignedArithmetic... Num>
auto negativeSum(Num... num) {
return (negate(num) + ...);
}
int main() {
std::vector<int> lst{10, 42, -3141};
// Whoops, our predicate lacks a parameter
bibi::sort(lst.begin(), lst.end(), [](auto &){ return true; });
std::cout << negativeSum(1, 2, 3.0, 4ll) << std::endl;
return 0;
}
Resulting compiler output (gcc 7.0 trunk):
demo.cpp: In function ‘int main()’:
demo.cpp:23:63: error: no matching function for call to ‘sort(std::vector<int>::iterator, std::vector<int>::iterator, main()::<lambda(auto:67&)>)’
bibi::sort(lst.begin(), lst.end(), [](auto &){ return true; });
^
In file included from demo.cpp:2:0:
/usr/include/bibi/Algorithm.h:345:6: note: candidate: template<class auto:63> requires RandomAccessIterator<auto:63> auto bibi::sort(auto:63, auto:63)
auto sort(RandomAccessIterator first, RandomAccessIterator last)
^~~~
/usr/include/bibi/Algorithm.h:345:6: note: template argument deduction/substitution failed:
demo.cpp:23:63: note: candidate expects 2 arguments, 3 provided
bibi::sort(lst.begin(), lst.end(), [](auto &){ return true; });
^
In file included from demo.cpp:2:0:
/usr/include/bibi/Algorithm.h:350:6: note: candidate: auto bibi::sort(auto:64, auto:64, auto:65) [with auto:64 = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; auto:65 = main()::<lambda(auto:67&)>]
auto sort(RandomAccessIterator first, RandomAccessIterator last, Compare<decltype(*first)> comp)
^~~~
/usr/include/bibi/Algorithm.h:350:6: note: constraints not satisfied
In file included from demo.cpp:1:0:
/usr/include/bibi/Core.h:74:14: note: within ‘template<class T, class U> concept const bool bibi::Compare<T, U> [with T = main()::<lambda(auto:67&)>; U = int&]’
concept bool Compare = Callable<T, bool, U, U>;
^~~~~~~
/usr/include/bibi/Core.h:20:14: note: within ‘template<class T, class R, class ... Args> concept const bool bibi::Callable<T, R, Args ...> [with T = main()::<lambda(auto:67&)>; R = bool; Args = {int&, int&}]’
concept bool Callable =
^~~~~~~~
/usr/include/bibi/Core.h:20:14: note: with ‘main()::<lambda(auto:67&)> t’
/usr/include/bibi/Core.h:20:14: note: with ‘int& args#0’
/usr/include/bibi/Core.h:20:14: note: with ‘int& args#1’
/usr/include/bibi/Core.h:20:14: note: the required expression ‘t(args ...)’ would be ill-formed
Comparison with calling std::sort directly:
In file included from /usr/include/c++/7.0.0/bits/stl_algobase.h:71:0,
from /usr/include/c++/7.0.0/bits/char_traits.h:39,
from /usr/include/c++/7.0.0/ios:40,
from /usr/include/c++/7.0.0/ostream:38,
from /usr/include/c++/7.0.0/iterator:64,
from /usr/include/bibi/Iterator.h:4,
from /usr/include/bibi/Algorithm.h:4,
from demo.cpp:2:
/usr/include/c++/7.0.0/bits/predefined_ops.h: In instantiation of ‘constexpr bool __gnu_cxx::__ops::_Iter_comp_iter<_Compare>::operator()(_Iterator1, _Iterator2) [with _Iterator1 = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Iterator2 = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Compare = main()::<lambda(auto:67&)>]’:
/usr/include/c++/7.0.0/bits/stl_algo.h:1844:14: required from ‘void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(auto:67&)> >]’
/usr/include/c++/7.0.0/bits/stl_algo.h:1882:25: required from ‘void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(auto:67&)> >]’
/usr/include/c++/7.0.0/bits/stl_algo.h:1968:31: required from ‘void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(auto:67&)> >]’
/usr/include/c++/7.0.0/bits/stl_algo.h:4778:18: required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Compare = main()::<lambda(auto:67&)>]’
demo.cpp:23:62: required from here
/usr/include/c++/7.0.0/bits/predefined_ops.h:123:18: error: no match for call to ‘(main()::<lambda(auto:67&)>) (int&, int&)’
{ return bool(_M_comp(*__it1, *__it2)); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
demo.cpp:23:45: note: candidate: template<class auto:67> constexpr main()::<lambda(auto:67&)>::operator decltype (((const main()::<lambda(auto:67&)>*)((const main()::<lambda(auto:67&)>* const)0u))->operator()(static_cast<auto:67&>(<anonymous>))) (*)(auto:67&)() const
std::sort(lst.begin(), lst.end(), [](auto &){ return true; });
^
demo.cpp:23:45: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/7.0.0/bits/stl_algobase.h:71:0,
from /usr/include/c++/7.0.0/bits/char_traits.h:39,
from /usr/include/c++/7.0.0/ios:40,
from /usr/include/c++/7.0.0/ostream:38,
from /usr/include/c++/7.0.0/iterator:64,
from /usr/include/bibi/Iterator.h:4,
from /usr/include/bibi/Algorithm.h:4,
from demo.cpp:2:
/usr/include/c++/7.0.0/bits/predefined_ops.h:123:18: note: candidate expects 1 argument, 2 provided
{ return bool(_M_comp(*__it1, *__it2)); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
demo.cpp:23:45: note: candidate: template<class auto:67> main()::<lambda(auto:67&)>
std::sort(lst.begin(), lst.end(), [](auto &){ return true; });
^
demo.cpp:23:45: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/7.0.0/bits/stl_algobase.h:71:0,
from /usr/include/c++/7.0.0/bits/char_traits.h:39,
from /usr/include/c++/7.0.0/ios:40,
from /usr/include/c++/7.0.0/ostream:38,
from /usr/include/c++/7.0.0/iterator:64,
from /usr/include/bibi/Iterator.h:4,
from /usr/include/bibi/Algorithm.h:4,
from demo.cpp:2:
/usr/include/c++/7.0.0/bits/predefined_ops.h:123:18: note: candidate expects 1 argument, 2 provided
{ return bool(_M_comp(*__it1, *__it2)); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/7.0.0/bits/predefined_ops.h: In instantiation of ‘bool __gnu_cxx::__ops::_Iter_comp_val<_Compare>::operator()(_Iterator, _Value&) [with _Iterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Value = int; _Compare = main()::<lambda(auto:67&)>]’:
/usr/include/c++/7.0.0/bits/stl_heap.h:129:48: required from ‘void std::__push_heap(_RandomAccessIterator, _Distance, _Distance, _Tp, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Distance = long int; _Tp = int; _Compare = __gnu_cxx::__ops::_Iter_comp_val<main()::<lambda(auto:67&)> >]’
/usr/include/c++/7.0.0/bits/stl_heap.h:230:23: required from ‘void std::__adjust_heap(_RandomAccessIterator, _Distance, _Distance, _Tp, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Distance = long int; _Tp = int; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(auto:67&)> >]’
/usr/include/c++/7.0.0/bits/stl_heap.h:335:22: required from ‘void std::__make_heap(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(auto:67&)> >]’
/usr/include/c++/7.0.0/bits/stl_algo.h:1669:23: required from ‘void std::__heap_select(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(auto:67&)> >]’
/usr/include/c++/7.0.0/bits/stl_algo.h:1930:25: required from ‘void std::__partial_sort(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(auto:67&)> >]’
/usr/include/c++/7.0.0/bits/stl_algo.h:1945:27: required from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Size = long int; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(auto:67&)> >]’
/usr/include/c++/7.0.0/bits/stl_algo.h:1965:25: required from ‘void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(auto:67&)> >]’
/usr/include/c++/7.0.0/bits/stl_algo.h:4778:18: required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Compare = main()::<lambda(auto:67&)>]’
demo.cpp:23:62: required from here
/usr/include/c++/7.0.0/bits/predefined_ops.h:144:11: error: no match for call to ‘(main()::<lambda(auto:67&)>) (int&, int&)’
{ return bool(_M_comp(*__it, __val)); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~
demo.cpp:23:45: note: candidate: template<class auto:67> constexpr main()::<lambda(auto:67&)>::operator decltype (((const main()::<lambda(auto:67&)>*)((const main()::<lambda(auto:67&)>* const)0u))->operator()(static_cast<auto:67&>(<anonymous>))) (*)(auto:67&)() const
std::sort(lst.begin(), lst.end(), [](auto &){ return true; });
^
demo.cpp:23:45: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/7.0.0/bits/stl_algobase.h:71:0,
from /usr/include/c++/7.0.0/bits/char_traits.h:39,
from /usr/include/c++/7.0.0/ios:40,
from /usr/include/c++/7.0.0/ostream:38,
from /usr/include/c++/7.0.0/iterator:64,
from /usr/include/bibi/Iterator.h:4,
from /usr/include/bibi/Algorithm.h:4,
from demo.cpp:2:
/usr/include/c++/7.0.0/bits/predefined_ops.h:144:11: note: candidate expects 1 argument, 2 provided
{ return bool(_M_comp(*__it, __val)); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~
demo.cpp:23:45: note: candidate: template<class auto:67> main()::<lambda(auto:67&)>
std::sort(lst.begin(), lst.end(), [](auto &){ return true; });
^
demo.cpp:23:45: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/7.0.0/bits/stl_algobase.h:71:0,
from /usr/include/c++/7.0.0/bits/char_traits.h:39,
from /usr/include/c++/7.0.0/ios:40,
from /usr/include/c++/7.0.0/ostream:38,
from /usr/include/c++/7.0.0/iterator:64,
from /usr/include/bibi/Iterator.h:4,
from /usr/include/bibi/Algorithm.h:4,
from demo.cpp:2:
/usr/include/c++/7.0.0/bits/predefined_ops.h:144:11: note: candidate expects 1 argument, 2 provided
{ return bool(_M_comp(*__it, __val)); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7.0.0/algorithm:62:0,
from /usr/include/bibi/Algorithm.h:5,
from demo.cpp:2:
/usr/include/c++/7.0.0/bits/stl_algo.h:1818:5: warning: ‘void std::__unguarded_linear_insert(_RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Compare = __gnu_cxx::__ops::_Val_comp_iter<main()::<lambda(auto:67&)> >]’ used but never defined
__unguarded_linear_insert(_RandomAccessIterator __last,
^~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7.0.0/bits/stl_algobase.h:71:0,
from /usr/include/c++/7.0.0/bits/char_traits.h:39,
from /usr/include/c++/7.0.0/ios:40,
from /usr/include/c++/7.0.0/ostream:38,
from /usr/include/c++/7.0.0/iterator:64,
from /usr/include/bibi/Iterator.h:4,
from /usr/include/bibi/Algorithm.h:4,
from demo.cpp:2:
/usr/include/c++/7.0.0/bits/predefined_ops.h:179:5: warning: ‘__gnu_cxx::__ops::_Val_comp_iter<_Compare> __gnu_cxx::__ops::__val_comp_iter(__gnu_cxx::__ops::_Iter_comp_iter<_Compare>) [with _Compare = main()::<lambda(auto:67&)>]’ used but never defined
__val_comp_iter(_Iter_comp_iter<_Compare> __comp)
^~~~~~~~~~~~~~~
Requirements¶
- A compiler with support for the Concepts Lite TS (at the time of writing, this only applies to gcc >= 6.1)
- A C++14 compliant standard library
- CMake 3.6 - Older Versions are very likely to work
What is mostly working¶
- Allocator (although optional constraints are not implemented)
- Type Traits
- Core Concepts
- Iterator
- Chrono
- Random
- Thread
- The algorithm header
- A very early Boost.GIL implementation
What is not working¶
- The numerics header has not been started yet
- Container Concepts are lacking, to say the least
- TimedLockable and SharedTimedMutex are underconstrained (possibly a gcc bug?)
- Some Random Concepts are underconstrined due to a gcc bug (a workaround is possible, but not implemented yet)
- TrivialClock is underconstrained (does not recursively check the constraints)
What would be nice in the future¶
- More tests (a lot more)
- Extending the Library to some Boost Concepts, most notably Boost.graph and Boost.asio
- Extending to the Ranges TS or range-v3
Documentation¶
License¶
This library is released under the Boost Software License 1.0.