1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use std::collections::{BTreeMap, HashMap, LinkedList};
use std::hash::Hash;

use crate::{Borrow, BorrowMut};

impl BorrowMut for String {
    type TargetMut<'a> = &'a mut String;

    #[inline]
    fn borrow_mut(&mut self) -> Self::TargetMut<'_> {
        self
    }
}

macro_rules! seq {
    (cap $seq:ident, $insert:ident $(, $trait:path)* $(,)?) => {
        impl<T> BorrowMut for $seq<T>
        where
            T: BorrowMut,
            $(for<'a> T::TargetMut<'a>: $trait,)*
        {
            type TargetMut<'a> = $seq<T::TargetMut<'a>> where T: 'a;

            #[inline]
            fn borrow_mut(&mut self) -> Self::TargetMut<'_> {
                let mut out = <$seq<_>>::with_capacity(self.len());

                for value in self {
                    out.$insert(value.borrow_mut());
                }

                out
            }
        }
    };

    ($seq:ident, $insert:ident $(, $trait:path)* $(,)?) => {
        impl<T> BorrowMut for $seq<T>
        where
            T: BorrowMut,
            $(for<'a> T::TargetMut<'a>: $trait,)*
        {
            type TargetMut<'a> = $seq<T::TargetMut<'a>> where T: 'a;

            #[inline]
            fn borrow_mut(&mut self) -> Self::TargetMut<'_> {
                let mut out = <$seq<_>>::new();

                for value in self {
                    out.$insert(value.borrow_mut());
                }

                out
            }
        }
    };
}

macro_rules! map {
    (cap $map:ident, $insert:ident $(, $trait:path)* $(,)?) => {
        impl<K, V> BorrowMut for $map<K, V>
        where
            K: Borrow,
            V: BorrowMut,
            $(for<'a> K::Target<'a>: $trait,)*
        {
            type TargetMut<'a> = $map<K::Target<'a>, V::TargetMut<'a>> where K: 'a, V: 'a;

            #[inline]
            fn borrow_mut(&mut self) -> Self::TargetMut<'_> {
                let mut out = <$map<_, _>>::with_capacity(self.len());

                for (key, value) in self {
                    out.$insert(key.borrow(), value.borrow_mut());
                }

                out
            }
        }
    };

    ($map:ident, $insert:ident $(, $trait:path)* $(,)?) => {
        impl<K, V> BorrowMut for $map<K, V>
        where
            K: Borrow,
            V: BorrowMut,
            $(for<'a> K::Target<'a>: $trait,)*
        {
            type TargetMut<'a> = $map<K::Target<'a>, V::TargetMut<'a>> where K: 'a, V: 'a;

            #[inline]
            fn borrow_mut(&mut self) -> Self::TargetMut<'_> {
                let mut out = <$map<_, _>>::new();

                for (key, value) in self {
                    out.$insert(key.borrow(), value.borrow_mut());
                }

                out
            }
        }
    };
}

seq!(cap Vec, push);
seq!(LinkedList, push_back);

map!(cap HashMap, insert, Hash, Eq);
map!(BTreeMap, insert, PartialOrd, Ord, Eq);