// bslstl_ranges.h                                                    -*-C++-*-
#ifndef INCLUDED_BSLSTL_RANGES
#define INCLUDED_BSLSTL_RANGES

#include <bsls_ident.h>
BSLS_IDENT("$Id: $")

//@PURPOSE: Provide functionality of the corresponding C++ Standard header.
//
//@CANONICAL_HEADER: bsl_ranges.h
//
//@DESCRIPTION: Provide types, in the `bsl` namespace, equivalent to those
// defined in the corresponding C++ standard header.  Include the native
// compiler-provided standard header, and also directly include Bloomberg's
// implementation of the C++ standard type (if one exists).  Finally, place the
// included symbols from the `std` namespace (if any) into the `bsl` namespace.

#include <bslstl_iterator.h>

#include <bslma_bslallocator.h>

#include <bsls_compilerfeatures.h>
#include <bsls_keyword.h>
#include <bsls_libraryfeatures.h>

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES

#if !defined(BSLS_LIBRARYFEATURES_STDCPP_LLVM) || _LIBCPP_VERSION > 179999
    #define BSL_RANGES_HAS_JOIN_VIEW                                          1
#endif

#include <ranges>

namespace bsl {

namespace ranges {

    // Range access (defined in `bststl_iterator.h`)
    //using std::ranges::begin;
    //using std::ranges::end;
    //using std::ranges::cbegin;
    //using std::ranges::cend;
    //using std::ranges::rbegin;
    //using std::ranges::rend;
    //using std::ranges::crbegin;
    //using std::ranges::crend;
    //using std::ranges::size;
    //using std::ranges::ssize;
    //using std::ranges::empty;
    //using std::ranges::data;
    //using std::ranges::cdata;

    // Range primitives
    using std::ranges::iterator_t;
    using std::ranges::sentinel_t;
    using std::ranges::range_size_t;
    using std::ranges::range_difference_t;
    using std::ranges::range_value_t;
    using std::ranges::range_reference_t;
    using std::ranges::range_rvalue_reference_t;

    // Not yet added
    // https://cplusplus.github.io/LWG/issue386
    // using std::ranges::range_common_reference_t;

    // Range concepts
    using std::ranges::range;
    using std::ranges::borrowed_range;
    using std::ranges::enable_borrowed_range;
    using std::ranges::sized_range;
    using std::ranges::disable_sized_range;
    using std::ranges::view;
    using std::ranges::enable_view;
    using std::ranges::view_base;

    using std::ranges::input_range;
    using std::ranges::output_range;
    using std::ranges::forward_range;
    using std::ranges::bidirectional_range;
    using std::ranges::random_access_range;
    using std::ranges::contiguous_range;
    using std::ranges::common_range;
    using std::ranges::viewable_range;

    // Views
    using std::ranges::view_interface;
    using std::ranges::subrange;

    // Dangling iterator handling
    using std::ranges::dangling;
    using std::ranges::borrowed_iterator_t;
    using std::ranges::borrowed_subrange_t;

    // Factories
    using std::ranges::empty_view;
    using std::ranges::single_view;
    using std::ranges::iota_view;
    using std::ranges::basic_istream_view;
    using std::ranges::istream_view;
    using std::ranges::wistream_view;

namespace views {

    using std::ranges::views::empty;
    using std::ranges::views::single;
    using std::ranges::views::iota;
    using std::ranges::views::istream;

}  // close namespace views

    // Adaptors
    using std::ranges::ref_view;
    using std::ranges::owning_view;
    using std::ranges::filter_view;
    using std::ranges::transform_view;
    using std::ranges::take_view;
    using std::ranges::take_while_view;
    using std::ranges::drop_view;
    using std::ranges::drop_while_view;
#if BSL_RANGES_HAS_JOIN_VIEW
    using std::ranges::join_view;
#endif
    using std::ranges::lazy_split_view;
    using std::ranges::split_view;
    using std::ranges::common_view;
    using std::ranges::reverse_view;
    using std::ranges::elements_view;
    using std::ranges::keys_view;
    using std::ranges::values_view;

namespace views {

    using std::ranges::views::all_t;
    using std::ranges::views::all;
    using std::ranges::views::counted;
    using std::ranges::views::filter;
    using std::ranges::views::transform;
    using std::ranges::views::take;
    using std::ranges::views::take_while;
    using std::ranges::views::drop;
    using std::ranges::views::drop_while;
#if BSL_RANGES_HAS_JOIN_VIEW
    using std::ranges::views::join;
#endif
    using std::ranges::views::lazy_split;
    using std::ranges::views::split;
    using std::ranges::views::common;
    using std::ranges::views::reverse;
    using std::ranges::views::elements;
    using std::ranges::views::keys;
    using std::ranges::views::values;

}  // close namespace views

    // Enumerations
    using std::ranges::subrange_kind;

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_BASELINE_LIBRARY
    using std::ranges::as_rvalue_view;
    using std::ranges::chunk_by_view;
    using std::ranges::repeat_view;
    namespace views {
        using std::views::as_rvalue;
        using std::views::chunk_by;
        using std::views::repeat;
    }
#endif

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_TO_CONTAINER
    using std::ranges::to;
#endif

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_RANGE_ADAPTOR_CLOSURE
    using std::ranges::range_adaptor_closure;
#endif

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_AS_CONST
    using std::ranges::const_iterator_t;
    using std::ranges::const_sentinel_t;
    using std::ranges::range_const_reference_t;
    using std::ranges::constant_range;
    using std::ranges::as_const_view;
    namespace views {
        using std::views::as_const;
    }
#endif

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_CARTESIAN_PRODUCT
    using std::ranges::cartesian_product_view;
    namespace views {
        using std::views::cartesian_product;
    }
#endif

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_CHUNK
    using std::ranges::chunk_view;
    namespace views {
        using std::views::chunk;
    }
#endif

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_ENUMERATE
    using std::ranges::enumerate_view;
    namespace views {
        using std::views::enumerate;
    }
#endif

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_JOIN_WITH
    using std::ranges::join_with_view;
    namespace views {
        using std::views::join_with;
    }
#endif

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_SLIDE
    using std::ranges::slide_view;
    namespace views {
        using std::views::slide;
    }
#endif

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_STRIDE
    using std::ranges::stride_view;
    namespace views {
        using std::views::stride;
    }
#endif

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_ZIP
    using std::ranges::adjacent_view;
    using std::ranges::adjacent_transform_view;
    using std::ranges::zip_view;
    using std::ranges::zip_transform_view;
    namespace views {
        using std::views::adjacent;
        using std::views::adjacent_transform;
        using std::views::zip;
        using std::views::zip_transform;
    }
#endif

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_GENERATOR
    template<ranges::range R, class Alloc = bsl::allocator<>>
    using elements_of = std::ranges::elements_of<R, Alloc>;
#endif

}  // close namespace ranges

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_CONTAINERS_RANGES
using std::from_range;
using std::from_range_t;
#endif

    // Namespace alias
    namespace views = ranges::views;

}  // close package namespace

#endif  // BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES

#ifndef BSLS_LIBRARYFEATURES_HAS_CPP23_CONTAINERS_RANGES
namespace bsl {

struct from_range_t {
#ifdef BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS
    explicit from_range_t() = default;
#endif
};

#ifdef BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES
inline constexpr from_range_t from_range = from_range_t();
#else
extern const from_range_t from_range;
#endif

}  // close package namespace
#endif  // BSLS_LIBRARYFEATURES_HAS_CPP23_CONTAINERS_RANGES

#endif

// ----------------------------------------------------------------------------
// Copyright 2025 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
