Amortized constant complexity for insertion at the front is (typically) achieved by assigning from the middle of the vector of pointers outwards.
For example, if we have a deque with 3 nodes, each holding up to 4 elements, we might assign its vector of 8 pointers thus:
[ nil, nil, nil, N1*, N2*, N3*, nil, nil ]
Here N1 and N3 might themselves be partially filled:
N1: [ nil, nil, nil, 1 ]
N2: [ 2, 3, 4, 5 ]
N3: [ 6, 7, nil, nil ]
As we push_front onto the deque, first N1 is filled towards the front, then additional nodes are allocated and added to the vector of pointers. Once the vector of pointers is filled at the front, any additional push_front results in an exponential expansion with the additional space assigned at the front:
[ N1*, N2*, N3*, N4*, N5*, N6*, nil, nil ]
| `---------------------------------------\
`-----------------------------------v v
[ nil, nil, nil, nil, nil, nil, nil, N0*, N1*, N2*, N3*, N4*, N5*, N6*, nil, nil ]
This exponential growth policy achieves O(1) amortized complexity for both deque::push_front and deque::push_back for the same reason that vector::push_back has O(1) amortized complexity.