Skip to content

feat+refactor: Bump MSRV to 1.57 and maximize const #296

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -17,23 +17,21 @@ jobs:
strategy:
matrix:
include:
- rust: 1.51.0 # MSRV
- rust: 1.57.0 # MSRV
features: serde
experimental: false
# doctest of `ArrayVec::spare_capacity_mut` has MSRV 1.55
test-args: --skip spare_capacity_mut
- rust: 1.70.0
features: serde
experimental: false
- rust: stable
features:
features: const
bench: true
experimental: false
- rust: beta
features: serde
features: serde, const
experimental: false
- rust: nightly
features: serde, borsh, zeroize
features: serde, borsh, zeroize, const
experimental: false

steps:
@@ -42,7 +40,7 @@ jobs:
with:
toolchain: ${{ matrix.rust }}
- name: Pin versions for MSRV
if: "${{ matrix.rust == '1.51.0' }}"
if: "${{ matrix.rust == '1.57.0' }}"
run: |
cargo update -p serde_test --precise 1.0.163
cargo update -p serde --precise 1.0.69
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ version = "0.7.6"
authors = ["bluss"]
license = "MIT OR Apache-2.0"
edition = "2018"
rust-version = "1.51"
rust-version = "1.57"

description = "A vector with fixed capacity, backed by an array (it can be stored on the stack too). Implements fixed capacity ArrayVec and ArrayString."
documentation = "https://docs.rs/arrayvec/"
@@ -48,14 +48,15 @@ harness = false
[features]
default = ["std"]
std = []
const = []

[profile.bench]
debug = true
[profile.release]
debug = true

[package.metadata.docs.rs]
features = ["borsh", "serde", "zeroize"]
features = ["borsh", "serde", "zeroize", "const"]

[package.metadata.release]
no-dev-version = true
96 changes: 57 additions & 39 deletions src/array_string.rs
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ use crate::CapacityError;
use crate::LenUint;
use crate::char::encode_utf8;
use crate::utils::MakeMaybeUninit;
use crate::const_fn;

#[cfg(feature="serde")]
use serde::{Serialize, Deserialize, Serializer, Deserializer};
@@ -50,6 +51,8 @@ impl<const CAP: usize> Default for ArrayString<CAP>

impl<const CAP: usize> ArrayString<CAP>
{

const_fn!{
/// Create a new empty `ArrayString`.
///
/// Capacity is inferred from the type parameter.
@@ -62,12 +65,12 @@ impl<const CAP: usize> ArrayString<CAP>
/// assert_eq!(&string[..], "foo");
/// assert_eq!(string.capacity(), 16);
/// ```
pub fn new() -> ArrayString<CAP> {
pub const fn new() -> ArrayString<CAP> {
assert_capacity_limit!(CAP);
unsafe {
ArrayString { xs: MaybeUninit::uninit().assume_init(), len: 0 }
}
}
}}

/// Create a new empty `ArrayString` (const fn).
///
@@ -91,6 +94,7 @@ impl<const CAP: usize> ArrayString<CAP>
#[inline]
pub const fn is_empty(&self) -> bool { self.len() == 0 }

const_fn!{
/// Create a new `ArrayString` from a `str`.
///
/// Capacity is inferred from the type parameter.
@@ -105,12 +109,15 @@ impl<const CAP: usize> ArrayString<CAP>
/// assert_eq!(string.len(), 3);
/// assert_eq!(string.capacity(), 3);
/// ```
pub fn from(s: &str) -> Result<Self, CapacityError<&str>> {
pub const fn from(s: &str) -> Result<Self, CapacityError<&str>> {
let mut arraystr = Self::new();
arraystr.try_push_str(s)?;
Ok(arraystr)
}
match arraystr.try_push_str(s) {
Ok(()) => Ok(arraystr),
Err(e) => Err(e),
}
}}

const_fn!{
/// Create a new `ArrayString` from a byte string literal.
///
/// **Errors** if the byte string literal is not valid UTF-8.
@@ -120,18 +127,22 @@ impl<const CAP: usize> ArrayString<CAP>
///
/// let string = ArrayString::from_byte_string(b"hello world").unwrap();
/// ```
pub fn from_byte_string(b: &[u8; CAP]) -> Result<Self, Utf8Error> {
let len = str::from_utf8(b)?.len();
debug_assert_eq!(len, CAP);
pub const fn from_byte_string(b: &[u8; CAP]) -> Result<Self, Utf8Error> {
let len = match str::from_utf8(b) {
Ok(str) => str.len(),
Err(e) => return Err(e),
};
debug_assert!(len == CAP);
let mut vec = Self::new();
unsafe {
(b as *const [u8; CAP] as *const [MaybeUninit<u8>; CAP])
.copy_to_nonoverlapping(&mut vec.xs as *mut [MaybeUninit<u8>; CAP], 1);
vec.set_len(CAP);
}
Ok(vec)
}
}}

const_fn!{
/// Create a new `ArrayString` value fully filled with ASCII NULL characters (`\0`). Useful
/// to be used as a buffer to collect external data or as a buffer for intermediate processing.
///
@@ -142,7 +153,7 @@ impl<const CAP: usize> ArrayString<CAP>
/// assert_eq!(string.len(), 16);
/// ```
#[inline]
pub fn zero_filled() -> Self {
pub const fn zero_filled() -> Self {
assert_capacity_limit!(CAP);
// SAFETY: `assert_capacity_limit` asserts that `len` won't overflow and
// `zeroed` fully fills the array with nulls.
@@ -152,7 +163,7 @@ impl<const CAP: usize> ArrayString<CAP>
len: CAP as _
}
}
}
}}

/// Return the capacity of the `ArrayString`.
///
@@ -209,6 +220,7 @@ impl<const CAP: usize> ArrayString<CAP>
self.try_push(c).unwrap();
}

const_fn!{
/// Adds the given char to the end of the string.
///
/// Returns `Ok` if the push succeeds.
@@ -227,7 +239,7 @@ impl<const CAP: usize> ArrayString<CAP>
/// assert_eq!(&string[..], "ab");
/// assert_eq!(overflow.unwrap_err().element(), 'c');
/// ```
pub fn try_push(&mut self, c: char) -> Result<(), CapacityError<char>> {
pub const fn try_push(&mut self, c: char) -> Result<(), CapacityError<char>> {
let len = self.len();
unsafe {
let ptr = self.as_mut_ptr().add(len);
@@ -240,7 +252,7 @@ impl<const CAP: usize> ArrayString<CAP>
Err(_) => Err(CapacityError::new(c)),
}
}
}
}}

/// Adds the given string slice to the end of the string.
///
@@ -261,6 +273,7 @@ impl<const CAP: usize> ArrayString<CAP>
self.try_push_str(s).unwrap()
}

const_fn!{
/// Adds the given string slice to the end of the string.
///
/// Returns `Ok` if the push succeeds.
@@ -281,7 +294,7 @@ impl<const CAP: usize> ArrayString<CAP>
/// assert_eq!(overflow1.unwrap_err().element(), "bc");
/// assert_eq!(overflow2.unwrap_err().element(), "ef");
/// ```
pub fn try_push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> {
pub const fn try_push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> {
if s.len() > self.capacity() - self.len() {
return Err(CapacityError::new(s));
}
@@ -293,7 +306,7 @@ impl<const CAP: usize> ArrayString<CAP>
self.set_len(newl);
}
Ok(())
}
}}

/// Removes the last character from the string and returns it.
///
@@ -340,7 +353,7 @@ impl<const CAP: usize> ArrayString<CAP>
/// ```
pub fn truncate(&mut self, new_len: usize) {
if new_len <= self.len() {
assert!(self.is_char_boundary(new_len));
assert!(self.as_str().is_char_boundary(new_len));
unsafe {
// In libstd truncate is called on the underlying vector,
// which in turns drops each element.
@@ -387,68 +400,73 @@ impl<const CAP: usize> ArrayString<CAP>
ch
}

const_fn!{
/// Make the string empty.
pub fn clear(&mut self) {
pub const fn clear(&mut self) {
unsafe {
self.set_len(0);
}
}
}}

const_fn!{
/// Set the strings’s length.
///
/// This function is `unsafe` because it changes the notion of the
/// number of “valid” bytes in the string. Use with care.
///
/// This method uses *debug assertions* to check the validity of `length`
/// and may use other debug assertions.
pub unsafe fn set_len(&mut self, length: usize) {
pub const unsafe fn set_len(&mut self, length: usize) {
// type invariant that capacity always fits in LenUint
debug_assert!(length <= self.capacity());
self.len = length as LenUint;
}
}}

const_fn!{
/// Return a string slice of the whole `ArrayString`.
pub fn as_str(&self) -> &str {
self
}
pub const fn as_str(&self) -> &str {
unsafe {
let sl = slice::from_raw_parts(self.as_ptr(), self.len());
str::from_utf8_unchecked(sl)
}
}}

const_fn!{
/// Return a mutable string slice of the whole `ArrayString`.
pub fn as_mut_str(&mut self) -> &mut str {
self
}
pub const fn as_mut_str(&mut self) -> &mut str {
unsafe {
let len = self.len();
let sl = slice::from_raw_parts_mut(self.as_mut_ptr(), len);
str::from_utf8_unchecked_mut(sl)
}
}}

/// Return a raw pointer to the string's buffer.
pub fn as_ptr(&self) -> *const u8 {
pub const fn as_ptr(&self) -> *const u8 {
self.xs.as_ptr() as *const u8
}

const_fn!{
/// Return a raw mutable pointer to the string's buffer.
pub fn as_mut_ptr(&mut self) -> *mut u8 {
pub const fn as_mut_ptr(&mut self) -> *mut u8 {
self.xs.as_mut_ptr() as *mut u8
}
}}
}

impl<const CAP: usize> Deref for ArrayString<CAP>
{
type Target = str;
#[inline]
fn deref(&self) -> &str {
unsafe {
let sl = slice::from_raw_parts(self.as_ptr(), self.len());
str::from_utf8_unchecked(sl)
}
self.as_str()
}
}

impl<const CAP: usize> DerefMut for ArrayString<CAP>
{
#[inline]
fn deref_mut(&mut self) -> &mut str {
unsafe {
let len = self.len();
let sl = slice::from_raw_parts_mut(self.as_mut_ptr(), len);
str::from_utf8_unchecked_mut(sl)
}
self.as_mut_str()
}
}

177 changes: 102 additions & 75 deletions src/arrayvec.rs
Original file line number Diff line number Diff line change
@@ -22,8 +22,8 @@ use serde::{Serialize, Deserialize, Serializer, Deserializer};

use crate::LenUint;
use crate::errors::CapacityError;
use crate::arrayvec_impl::ArrayVecImpl;
use crate::utils::MakeMaybeUninit;
use crate::const_fn;

/// A vector with a fixed capacity.
///
@@ -65,6 +65,7 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
/// Capacity
const CAPACITY: usize = CAP;

const_fn!{
/// Create a new empty `ArrayVec`.
///
/// The maximum capacity is given by the generic parameter `CAP`.
@@ -80,12 +81,12 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
/// ```
#[inline]
#[track_caller]
pub fn new() -> ArrayVec<T, CAP> {
pub const fn new() -> ArrayVec<T, CAP> {
assert_capacity_limit!(CAP);
unsafe {
ArrayVec { xs: MaybeUninit::uninit().assume_init(), len: 0 }
}
}
}}

/// Create a new empty `ArrayVec` (const fn).
///
@@ -177,9 +178,10 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
/// ```
#[track_caller]
pub fn push(&mut self, element: T) {
ArrayVecImpl::push(self, element)
self.try_push(element).unwrap()
}

const_fn!{
/// Push `element` to the end of the vector.
///
/// Return `Ok` if the push succeeds, or return an error if the vector
@@ -202,10 +204,18 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
///
/// assert!(overflow.is_err());
/// ```
pub fn try_push(&mut self, element: T) -> Result<(), CapacityError<T>> {
ArrayVecImpl::try_push(self, element)
}
pub const fn try_push(&mut self, element: T) -> Result<(), CapacityError<T>> {
if self.len() < Self::CAPACITY {
unsafe {
self.push_unchecked(element);
}
Ok(())
} else {
Err(CapacityError::new(element))
}
}}

const_fn!{
/// Push `element` to the end of the vector without checking the capacity.
///
/// It is up to the caller to ensure the capacity of the vector is
@@ -227,9 +237,12 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
///
/// assert_eq!(&array[..], &[1, 2]);
/// ```
pub unsafe fn push_unchecked(&mut self, element: T) {
ArrayVecImpl::push_unchecked(self, element)
}
pub const unsafe fn push_unchecked(&mut self, element: T) {
let len = self.len();
debug_assert!(len < Self::CAPACITY);
ptr::write(self.as_mut_ptr().add(len), element);
self.set_len(len + 1);
}}

/// Shortens the vector, keeping the first `len` elements and dropping
/// the rest.
@@ -247,19 +260,27 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
/// assert_eq!(&array[..], &[1, 2, 3]);
/// ```
pub fn truncate(&mut self, new_len: usize) {
ArrayVecImpl::truncate(self, new_len)
unsafe {
let len = self.len();
if new_len < len {
self.set_len(new_len);
let tail = slice::from_raw_parts_mut(self.as_mut_ptr().add(new_len), len - new_len);
ptr::drop_in_place(tail);
}
}
}

/// Remove all elements in the vector.
pub fn clear(&mut self) {
ArrayVecImpl::clear(self)
self.truncate(0)
}


const_fn!{
/// Get pointer to where element at `index` would be
unsafe fn get_unchecked_ptr(&mut self, index: usize) -> *mut T {
const unsafe fn get_unchecked_ptr(&mut self, index: usize) -> *mut T {
self.as_mut_ptr().add(index)
}
}}

/// Insert `element` at position `index`.
///
@@ -332,6 +353,7 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
Ok(())
}

const_fn!{
/// Remove the last element in the vector and return it.
///
/// Return `Some(` *element* `)` if the vector is non-empty, else `None`.
@@ -346,9 +368,16 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
/// assert_eq!(array.pop(), Some(1));
/// assert_eq!(array.pop(), None);
/// ```
pub fn pop(&mut self) -> Option<T> {
ArrayVecImpl::pop(self)
}
pub const fn pop(&mut self) -> Option<T> {
if self.len() == 0 {
return None;
}
unsafe {
let new_len = self.len() - 1;
self.set_len(new_len);
Some(ptr::read(self.as_ptr().add(new_len)))
}
}}

/// Remove the element at `index` and swap the last element into its place.
///
@@ -535,6 +564,7 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
drop(g);
}

const_fn!{
/// Returns the remaining spare capacity of the vector as a slice of
/// `MaybeUninit<T>`.
///
@@ -565,24 +595,26 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
///
/// assert_eq!(&v[..], &[0, 1, 2]);
/// ```
pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
pub const fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
let len = self.len();
&mut self.xs[len..]
}
self.xs.split_at_mut(len).1
}}

const_fn!{
/// Set the vector’s length without dropping or moving out elements
///
/// This method is `unsafe` because it changes the notion of the
/// number of “valid” elements in the vector. Use with care.
///
/// This method uses *debug assertions* to check that `length` is
/// not greater than the capacity.
pub unsafe fn set_len(&mut self, length: usize) {
pub const unsafe fn set_len(&mut self, length: usize) {
// type invariant that capacity always fits in LenUint
debug_assert!(length <= self.capacity());
self.len = length as LenUint;
}
}}

const_fn!{
/// Copy all elements from the slice and append to the `ArrayVec`.
///
/// ```
@@ -601,7 +633,7 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
/// slice.
///
/// [`remaining_capacity`]: #method.remaining_capacity
pub fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), CapacityError>
pub const fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), CapacityError>
where T: Copy,
{
if self.remaining_capacity() < other.len() {
@@ -617,7 +649,7 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
self.set_len(self_len + other_len);
}
Ok(())
}
}}

/// Create a draining iterator that removes the specified range in the vector
/// and yields the removed items from start to end. The element range is
@@ -685,29 +717,32 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
}
}

const_fn!{
/// Return the inner fixed size array, if it is full to its capacity.
///
/// Return an `Ok` value with the array if length equals capacity,
/// return an `Err` with self otherwise.
pub fn into_inner(self) -> Result<[T; CAP], Self> {
pub const fn into_inner(self) -> Result<[T; CAP], Self> {
if self.len() < self.capacity() {
Err(self)
} else {
unsafe { Ok(self.into_inner_unchecked()) }
}
}
}}

const_fn!{
/// Return the inner fixed size array.
///
/// Safety:
/// This operation is safe if and only if length equals capacity.
pub unsafe fn into_inner_unchecked(self) -> [T; CAP] {
debug_assert_eq!(self.len(), self.capacity());
let self_ = ManuallyDrop::new(self);
let array = ptr::read(self_.as_ptr() as *const [T; CAP]);
array
}

pub const unsafe fn into_inner_unchecked(self) -> [T; CAP] {
debug_assert!(self.len() == self.capacity());
let ptr = self.as_ptr();
mem::forget(self);
ptr::read(ptr as *const [T; CAP])
}}

const_fn!{
/// Returns the ArrayVec, replacing the original with a new empty ArrayVec.
///
/// ```
@@ -717,49 +752,38 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
/// assert_eq!([0, 1, 2, 3], v.take().into_inner().unwrap());
/// assert!(v.is_empty());
/// ```
pub fn take(&mut self) -> Self {
mem::replace(self, Self::new())
}
pub const fn take(&mut self) -> Self {
mem::replace(self, Self::new_const())
}}

const_fn!{
/// Return a slice containing all elements of the vector.
pub fn as_slice(&self) -> &[T] {
ArrayVecImpl::as_slice(self)
}
pub const fn as_slice(&self) -> &[T] {
let len = self.len();
unsafe {
slice::from_raw_parts(self.as_ptr(), len)
}
}}

const_fn!{
/// Return a mutable slice containing all elements of the vector.
pub fn as_mut_slice(&mut self) -> &mut [T] {
ArrayVecImpl::as_mut_slice(self)
}
pub const fn as_mut_slice(&mut self) -> &mut [T] {
let len = self.len();
unsafe {
std::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
}
}}

/// Return a raw pointer to the vector's buffer.
pub fn as_ptr(&self) -> *const T {
ArrayVecImpl::as_ptr(self)
}

/// Return a raw mutable pointer to the vector's buffer.
pub fn as_mut_ptr(&mut self) -> *mut T {
ArrayVecImpl::as_mut_ptr(self)
}
}

impl<T, const CAP: usize> ArrayVecImpl for ArrayVec<T, CAP> {
type Item = T;
const CAPACITY: usize = CAP;

fn len(&self) -> usize { self.len() }

unsafe fn set_len(&mut self, length: usize) {
debug_assert!(length <= CAP);
self.len = length as LenUint;
}

fn as_ptr(&self) -> *const Self::Item {
pub const fn as_ptr(&self) -> *const T {
self.xs.as_ptr() as _
}

fn as_mut_ptr(&mut self) -> *mut Self::Item {
const_fn!{
/// Return a raw mutable pointer to the vector's buffer.
pub const fn as_mut_ptr(&mut self) -> *mut T {
self.xs.as_mut_ptr() as _
}
}}
}

impl<T, const CAP: usize> Deref for ArrayVec<T, CAP> {
@@ -916,15 +940,17 @@ pub struct IntoIter<T, const CAP: usize> {
v: ArrayVec<T, CAP>,
}
impl<T, const CAP: usize> IntoIter<T, CAP> {
const_fn!{
/// Returns the remaining items of this iterator as a slice.
pub fn as_slice(&self) -> &[T] {
&self.v[self.index..]
}
pub const fn as_slice(&self) -> &[T] {
self.v.as_slice().split_at(self.index).1
}}

const_fn!{
/// Returns the remaining items of this iterator as a mutable slice.
pub fn as_mut_slice(&mut self) -> &mut [T] {
&mut self.v[self.index..]
}
pub const fn as_mut_slice(&mut self) -> &mut [T] {
self.v.as_mut_slice().split_at_mut(self.index).1
}}
}

impl<T, const CAP: usize> Iterator for IntoIter<T, CAP> {
@@ -1100,7 +1126,7 @@ impl<T, const CAP: usize> Extend<T> for ArrayVec<T, CAP> {
#[inline(never)]
#[cold]
#[track_caller]
fn extend_panic() {
const fn extend_panic() {
panic!("ArrayVec: capacity exceeded in extend/from_iter");
}

@@ -1160,15 +1186,16 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
}
}

const_fn!{
/// Rawptr add but uses arithmetic distance for ZST
unsafe fn raw_ptr_add<T>(ptr: *mut T, offset: usize) -> *mut T {
const unsafe fn raw_ptr_add<T>(ptr: *mut T, offset: usize) -> *mut T {
if mem::size_of::<T>() == 0 {
// Special case for ZST
ptr.cast::<u8>().wrapping_add(offset).cast::<T>()
} else {
ptr.add(offset)
}
}
}}

/// Create an `ArrayVec` from an iterator.
///
87 changes: 0 additions & 87 deletions src/arrayvec_impl.rs

This file was deleted.

6 changes: 3 additions & 3 deletions src/char.rs
Original file line number Diff line number Diff line change
@@ -22,14 +22,15 @@ const MAX_THREE_B: u32 = 0x10000;
/// Placeholder
pub struct EncodeUtf8Error;

crate::const_fn!{
/// Encode a char into buf using UTF-8.
///
/// On success, return the byte length of the encoding (1, 2, 3 or 4).<br>
/// On error, return `EncodeUtf8Error` if the buffer was too short for the char.
///
/// Safety: `ptr` must be writable for `len` bytes.
#[inline]
pub unsafe fn encode_utf8(ch: char, ptr: *mut u8, len: usize) -> Result<usize, EncodeUtf8Error>
pub const unsafe fn encode_utf8(ch: char, ptr: *mut u8, len: usize) -> Result<usize, EncodeUtf8Error>
{
let code = ch as u32;
if code < MAX_ONE_B && len >= 1 {
@@ -52,7 +53,7 @@ pub unsafe fn encode_utf8(ch: char, ptr: *mut u8, len: usize) -> Result<usize, E
return Ok(4);
};
Err(EncodeUtf8Error)
}
}}


#[test]
@@ -89,4 +90,3 @@ fn test_encode_utf8_oob() {
}
}
}

21 changes: 19 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@
//!
//! ## Rust Version
//!
//! This version of arrayvec requires Rust 1.51 or later.
//! This version of arrayvec requires Rust 1.57 or later.
//!
#![doc(html_root_url="https://docs.rs/arrayvec/0.7/")]
#![cfg_attr(not(feature="std"), no_std)]
@@ -57,7 +57,6 @@ macro_rules! assert_capacity_limit_const {
}
}

mod arrayvec_impl;
mod arrayvec;
mod array_string;
mod char;
@@ -68,3 +67,21 @@ pub use crate::array_string::ArrayString;
pub use crate::errors::CapacityError;

pub use crate::arrayvec::{ArrayVec, IntoIter, Drain};

#[cfg(not(feature = "const"))]
macro_rules! const_fn {
($(#[$($metas:meta)*])* $v:vis const $($t:tt)+) => {
$(#[$($metas)*])*
$v $($t)+
};
}

#[cfg(feature = "const")]
macro_rules! const_fn {
($(#[$($metas:meta)*])* $v:vis const $($t:tt)+) => {
$(#[$($metas)*])*
$v const $($t)+
};
}

pub(crate) use const_fn;