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.

Get the Code

The source code repository is avaliable here.

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

License

This library is released under the Boost Software License 1.0.